home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / system-config-printer / system-config-printer.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-10-28  |  186KB  |  6,491 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import config
  5. import errno
  6. import sys
  7. import os
  8. import tempfile
  9. import time
  10. import traceback
  11. import re
  12. import httplib
  13. import glob
  14. import subprocess
  15. import signal
  16. import thread
  17. from timedops import *
  18. import dbus
  19.  
  20. try:
  21.     import gtk.glade as gtk
  22. except RuntimeError:
  23.     e = None
  24.     print 'system-config-printer:', e
  25.     print 'This is a graphical application and requires DISPLAY to be set.'
  26.     sys.exit(1)
  27.  
  28. import glib
  29.  
  30. def show_uri(uri):
  31.     gtk.show_uri(gtk.gdk.screen_get_default(), uri, gtk.get_current_event_time())
  32.  
  33. gtk.about_dialog_set_url_hook((lambda x, y: show_uri(y)))
  34. gtk.about_dialog_set_email_hook((lambda x, y: show_uri('mailto:' + y)))
  35.  
  36. def show_help():
  37.     print '\nThis is system-config-printer, a CUPS server configuration program.\n\nOptions:\n\n  --setup-printer URI\n            Select the (detected) CUPS device URI on start-up,\n            and run the new-printer wizard for it.\n\n  --configure-printer NAME\n            Select the named printer on start-up, and open its\n            properties dialog.\n\n  --choose-driver NAME\n            Select the named printer on start-up, and display\n            the list of drivers.\n\n  --print-test-page NAME\n            Select the named printer on start-up and print a\n            test page to it.\n\n  --no-focus-on-map\n            Do not focus the main window, to prevent focus \n            stealing\n\n  --debug   Enable debugging output.\n'
  38.  
  39. if len(sys.argv) > 1 and sys.argv[1] == '--help':
  40.     show_help()
  41.     sys.exit(0)
  42.  
  43. import cups
  44. cups.require('1.9.42')
  45.  
  46. try:
  47.     cups.ppdSetConformance(cups.PPD_CONFORM_RELAXED)
  48. except AttributeError:
  49.     pass
  50.  
  51.  
  52. try:
  53.     import pysmb
  54.     PYSMB_AVAILABLE = True
  55. except:
  56.     PYSMB_AVAILABLE = False
  57.  
  58. import cupshelpers
  59. import options
  60. import gobject
  61. from glade import GtkGUI
  62. from optionwidgets import OptionWidget
  63. from debug import *
  64. import probe_printer
  65. import gtk_label_autowrap
  66. import urllib
  67. import troubleshoot
  68. import jobviewer
  69. import authconn
  70. import monitor
  71. from smburi import SMBURI
  72. import errordialogs
  73. from errordialogs import *
  74. import installpackage
  75. import userdefault
  76. from AdvancedServerSettings import AdvancedServerSettingsDialog
  77. from PhysicalDevice import PhysicalDevice
  78. from ToolbarSearchEntry import *
  79. from GroupsPane import *
  80. from GroupsPaneModel import *
  81. from SearchCriterion import *
  82. import gtkinklevel
  83. import gtkspinner
  84. import statereason
  85. domain = 'system-config-printer'
  86. import locale
  87.  
  88. try:
  89.     locale.setlocale(locale.LC_ALL, '')
  90. except locale.Error:
  91.     os.environ['LC_ALL'] = 'C'
  92.     locale.setlocale(locale.LC_ALL, '')
  93.  
  94. from gettext import gettext as _
  95. monitor.set_gettext_function(_)
  96. errordialogs.set_gettext_function(_)
  97. authconn.set_gettext_function(_)
  98. import gettext
  99. gettext.textdomain(domain)
  100. gettext.bindtextdomain(domain, config.localedir)
  101. gtk.glade.textdomain(domain)
  102. gtk.glade.bindtextdomain(domain, config.localedir)
  103. import ppdippstr
  104. pkgdata = config.pkgdatadir
  105. iconpath = os.path.join(pkgdata, 'icons/')
  106. sys.path.append(pkgdata)
  107. busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
  108. TEXT_start_firewall_tool = _('To do this, select System->Administration->Firewall from the main menu.')
  109.  
  110. try:
  111.     try_CUPS_SERVER_REMOTE_ANY = cups.CUPS_SERVER_REMOTE_ANY
  112. except AttributeError:
  113.     try_CUPS_SERVER_REMOTE_ANY = '_remote_any'
  114.  
  115.  
  116. def validDeviceURI(uri):
  117.     '''Returns True is the provided URI is valid.'''
  118.     (scheme, rest) = urllib.splittype(uri)
  119.     if scheme == None or scheme == '':
  120.         return False
  121.     return True
  122.  
  123.  
  124. def CUPS_server_hostname():
  125.     host = cups.getServer()
  126.     if host[0] == '/':
  127.         return 'localhost'
  128.     return host
  129.  
  130.  
  131. def moveClassMembers(treeview_from, treeview_to):
  132.     selection = treeview_from.get_selection()
  133.     (model_from, rows) = selection.get_selected_rows()
  134.     rows = [ gtk.TreeRowReference(model_from, row) for row in rows ]
  135.     model_to = treeview_to.get_model()
  136.     for row in rows:
  137.         path = row.get_path()
  138.         iter = model_from.get_iter(path)
  139.         row_data = model_from.get(iter, 0)
  140.         model_to.append(row_data)
  141.         model_from.remove(iter)
  142.     
  143.  
  144.  
  145. def getCurrentClassMembers(treeview):
  146.     model = treeview.get_model()
  147.     iter = model.get_iter_root()
  148.     result = []
  149.     while iter:
  150.         result.append(model.get(iter, 0)[0])
  151.         iter = model.iter_next(iter)
  152.     result.sort()
  153.     return result
  154.  
  155.  
  156. def on_delete_just_hide(widget, event):
  157.     widget.hide()
  158.     return True
  159.  
  160.  
  161. class GUI(GtkGUI, monitor.Watcher):
  162.     printer_states = {
  163.         cups.IPP_PRINTER_IDLE: _('Idle'),
  164.         cups.IPP_PRINTER_PROCESSING: _('Processing'),
  165.         cups.IPP_PRINTER_BUSY: _('Busy'),
  166.         cups.IPP_PRINTER_STOPPED: _('Stopped') }
  167.     
  168.     def __init__(self, setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  169.         
  170.         try:
  171.             self.language = locale.getlocale(locale.LC_MESSAGES)
  172.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  173.         except:
  174.             nonfatalException()
  175.             os.environ['LC_ALL'] = 'C'
  176.             locale.setlocale(locale.LC_ALL, '')
  177.             self.language = locale.getlocale(locale.LC_MESSAGES)
  178.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  179.  
  180.         self.printer = None
  181.         self.conflicts = set()
  182.         if not self.printer or self.printer.getServer():
  183.             pass
  184.         self.connect_server = cups.getServer()
  185.         self.connect_encrypt = cups.getEncryption()
  186.         self.connect_user = cups.getUser()
  187.         self.changed = set()
  188.         self.servers = set((self.connect_server,))
  189.         self.server_is_publishing = False
  190.         self.devid = devid
  191.         self.focus_on_map = focus_on_map
  192.         self.updating_widgets = False
  193.         self.getWidgets({
  194.             'PrintersWindow': [
  195.                 'PrintersWindow',
  196.                 'view_area_vbox',
  197.                 'view_area_scrolledwindow',
  198.                 'dests_iconview',
  199.                 'statusbarMain',
  200.                 'toolbar',
  201.                 'server_settings_menu_entry',
  202.                 'new_printer',
  203.                 'new_class',
  204.                 'group_menubar_item',
  205.                 'printer_menubar_item',
  206.                 'view_discovered_printers',
  207.                 'view_groups'],
  208.             'AboutDialog': [
  209.                 'AboutDialog'],
  210.             'ConnectDialog': [
  211.                 'ConnectDialog',
  212.                 'chkEncrypted',
  213.                 'cmbServername',
  214.                 'btnConnect'],
  215.             'ConnectingDialog': [
  216.                 'ConnectingDialog',
  217.                 'lblConnecting',
  218.                 'pbarConnecting'],
  219.             'NewPrinterName': [
  220.                 'NewPrinterName',
  221.                 'entCopyName',
  222.                 'btnCopyOk'],
  223.             'ServerSettingsDialog': [
  224.                 'ServerSettingsDialog',
  225.                 'chkServerBrowse',
  226.                 'chkServerShare',
  227.                 'chkServerShareAny',
  228.                 'chkServerRemoteAdmin',
  229.                 'chkServerAllowCancelAll',
  230.                 'chkServerLogDebug',
  231.                 'hboxServerBrowse'],
  232.             'PrinterPropertiesDialog': [
  233.                 'PrinterPropertiesDialog',
  234.                 'tvPrinterProperties',
  235.                 'btnPrinterPropertiesCancel',
  236.                 'btnPrinterPropertiesOK',
  237.                 'btnPrinterPropertiesApply',
  238.                 'btnPrinterPropertiesClose',
  239.                 'ntbkPrinter',
  240.                 'entPDescription',
  241.                 'entPLocation',
  242.                 'lblPMakeModel',
  243.                 'lblPMakeModel2',
  244.                 'lblPState',
  245.                 'entPDevice',
  246.                 'lblPDevice2',
  247.                 'btnSelectDevice',
  248.                 'btnChangePPD',
  249.                 'chkPEnabled',
  250.                 'chkPAccepting',
  251.                 'chkPShared',
  252.                 'lblNotPublished',
  253.                 'btnPrintTestPage',
  254.                 'btnSelfTest',
  255.                 'btnCleanHeads',
  256.                 'btnConflict',
  257.                 'cmbPStartBanner',
  258.                 'cmbPEndBanner',
  259.                 'cmbPErrorPolicy',
  260.                 'cmbPOperationPolicy',
  261.                 'rbtnPAllow',
  262.                 'rbtnPDeny',
  263.                 'tvPUsers',
  264.                 'entPUser',
  265.                 'btnPAddUser',
  266.                 'btnPDelUser',
  267.                 'lblPInstallOptions',
  268.                 'swPInstallOptions',
  269.                 'vbPInstallOptions',
  270.                 'swPOptions',
  271.                 'lblPOptions',
  272.                 'vbPOptions',
  273.                 'algnClassMembers',
  274.                 'vbClassMembers',
  275.                 'lblClassMembers',
  276.                 'tvClassMembers',
  277.                 'tvClassNotMembers',
  278.                 'btnClassAddMember',
  279.                 'btnClassDelMember',
  280.                 'btnRefreshMarkerLevels',
  281.                 'tvPrinterStateReasons',
  282.                 'ntbkPrinterStateReasons',
  283.                 'sbJOCopies',
  284.                 'btnJOResetCopies',
  285.                 'cmbJOOrientationRequested',
  286.                 'btnJOResetOrientationRequested',
  287.                 'cbJOFitplot',
  288.                 'btnJOResetFitplot',
  289.                 'cmbJONumberUp',
  290.                 'btnJOResetNumberUp',
  291.                 'cmbJONumberUpLayout',
  292.                 'btnJOResetNumberUpLayout',
  293.                 'sbJOBrightness',
  294.                 'btnJOResetBrightness',
  295.                 'cmbJOFinishings',
  296.                 'btnJOResetFinishings',
  297.                 'sbJOJobPriority',
  298.                 'btnJOResetJobPriority',
  299.                 'cmbJOMedia',
  300.                 'btnJOResetMedia',
  301.                 'cmbJOSides',
  302.                 'btnJOResetSides',
  303.                 'cmbJOHoldUntil',
  304.                 'btnJOResetHoldUntil',
  305.                 'cbJOMirror',
  306.                 'btnJOResetMirror',
  307.                 'sbJOScaling',
  308.                 'btnJOResetScaling',
  309.                 'sbJOSaturation',
  310.                 'btnJOResetSaturation',
  311.                 'sbJOHue',
  312.                 'btnJOResetHue',
  313.                 'sbJOGamma',
  314.                 'btnJOResetGamma',
  315.                 'sbJOCpi',
  316.                 'btnJOResetCpi',
  317.                 'sbJOLpi',
  318.                 'btnJOResetLpi',
  319.                 'sbJOPageLeft',
  320.                 'btnJOResetPageLeft',
  321.                 'sbJOPageRight',
  322.                 'btnJOResetPageRight',
  323.                 'sbJOPageTop',
  324.                 'btnJOResetPageTop',
  325.                 'sbJOPageBottom',
  326.                 'btnJOResetPageBottom',
  327.                 'cbJOPrettyPrint',
  328.                 'btnJOResetPrettyPrint',
  329.                 'cbJOWrap',
  330.                 'btnJOResetWrap',
  331.                 'sbJOColumns',
  332.                 'btnJOResetColumns',
  333.                 'tblJOOther',
  334.                 'entNewJobOption',
  335.                 'btnNewJobOption',
  336.                 'vboxMarkerLevels',
  337.                 'btnRefreshMarkerLevels'] })
  338.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  339.         for dialog in [
  340.             self.PrinterPropertiesDialog,
  341.             self.ServerSettingsDialog]:
  342.             dialog.connect('delete-event', on_delete_just_hide)
  343.         
  344.         self.ConnectingDialog.connect('delete-event', self.on_connectingdialog_delete)
  345.         gtk.window_set_default_icon_name('printer')
  346.         self.btnNew = gtk.MenuToolButton('gtk-new')
  347.         self.btnNew.set_is_important(True)
  348.         newmenu = gtk.Menu()
  349.         newprinter = gtk.ImageMenuItem(_('Printer'))
  350.         printericon = gtk.Image()
  351.         printericon.set_from_icon_name('printer', gtk.ICON_SIZE_MENU)
  352.         newprinter.set_image(printericon)
  353.         newprinter.connect('activate', self.on_new_printer_activate)
  354.         self.btnNew.connect('clicked', self.on_new_printer_activate)
  355.         newclass = gtk.ImageMenuItem(_('Class'))
  356.         classicon = gtk.Image()
  357.         classicon.set_from_icon_name('gtk-dnd-multiple', gtk.ICON_SIZE_MENU)
  358.         newclass.set_image(classicon)
  359.         newclass.connect('activate', self.on_new_class_activate)
  360.         newprinter.show()
  361.         newclass.show()
  362.         newmenu.attach(newprinter, 0, 1, 0, 1)
  363.         newmenu.attach(newclass, 0, 1, 1, 2)
  364.         self.btnNew.set_menu(newmenu)
  365.         self.toolbar.add(self.btnNew)
  366.         self.toolbar.add(gtk.SeparatorToolItem())
  367.         refreshbutton = gtk.ToolButton('gtk-refresh')
  368.         refreshbutton.connect('clicked', self.on_btnRefresh_clicked)
  369.         self.toolbar.add(refreshbutton)
  370.         self.toolbar.show_all()
  371.         printer_manager_action_group = gtk.ActionGroup('PrinterManagerActionGroup')
  372.         printer_manager_action_group.add_actions([
  373.             ('rename-printer', None, _('_Rename'), None, None, self.on_rename_activate),
  374.             ('copy-printer', gtk.STOCK_COPY, None, '<Ctrl>c', None, self.on_copy_activate),
  375.             ('delete-printer', gtk.STOCK_DELETE, None, None, None, self.on_delete_activate),
  376.             ('set-default-printer', gtk.STOCK_HOME, _('Set As De_fault'), None, None, self.on_set_as_default_activate),
  377.             ('edit-printer', gtk.STOCK_PROPERTIES, None, None, None, self.on_edit_activate),
  378.             ('create-class', gtk.STOCK_DND_MULTIPLE, _('_Create class'), None, None, self.on_create_class_activate),
  379.             ('view-print-queue', gtk.STOCK_FIND, _('View Print _Queue'), None, None, self.on_view_print_queue_activate),
  380.             ('add-to-group', None, _('_Add to Group'), None, None, None),
  381.             ('save-as-group', None, _('Save Results as _Group'), None, None, self.on_save_as_group_activate),
  382.             ('save-as-search-group', None, _('Save Filter as _Search Group'), None, None, self.on_save_as_search_group_activate)])
  383.         printer_manager_action_group.add_toggle_actions([
  384.             ('enable-printer', None, _('E_nabled'), None, None, self.on_enabled_activate),
  385.             ('share-printer', None, _('_Shared'), None, None, self.on_shared_activate)])
  386.         printer_manager_action_group.add_radio_actions([
  387.             ('filter-name', None, _('Name')),
  388.             ('filter-description', None, _('Description')),
  389.             ('filter-location', None, _('Location')),
  390.             ('filter-manufacturer', None, _('Manufacturer / Model'))], 1, self.on_filter_criterion_changed)
  391.         for action in printer_manager_action_group.list_actions():
  392.             action.set_sensitive(False)
  393.         
  394.         printer_manager_action_group.get_action('view-print-queue').set_sensitive(True)
  395.         printer_manager_action_group.get_action('filter-name').set_sensitive(True)
  396.         printer_manager_action_group.get_action('filter-description').set_sensitive(True)
  397.         printer_manager_action_group.get_action('filter-location').set_sensitive(True)
  398.         printer_manager_action_group.get_action('filter-manufacturer').set_sensitive(True)
  399.         self.ui_manager = gtk.UIManager()
  400.         self.ui_manager.insert_action_group(printer_manager_action_group, -1)
  401.         self.ui_manager.add_ui_from_string('\n<ui>\n <accelerator action="rename-printer"/>\n <accelerator action="copy-printer"/>\n <accelerator action="delete-printer"/>\n <accelerator action="set-default-printer"/>\n <accelerator action="edit-printer"/>\n <accelerator action="create-class"/>\n <accelerator action="view-print-queue"/>\n <accelerator action="add-to-group"/>\n <accelerator action="save-as-group"/>\n <accelerator action="save-as-search-group"/>\n <accelerator action="enable-printer"/>\n <accelerator action="share-printer"/>\n <accelerator action="filter-name"/>\n <accelerator action="filter-description"/>\n <accelerator action="filter-location"/>\n <accelerator action="filter-manufacturer"/>\n</ui>\n')
  402.         self.ui_manager.ensure_update()
  403.         self.PrintersWindow.add_accel_group(self.ui_manager.get_accel_group())
  404.         self.printer_context_menu = gtk.Menu()
  405.         for action_name in [
  406.             'edit-printer',
  407.             'copy-printer',
  408.             'rename-printer',
  409.             'delete-printer',
  410.             None,
  411.             'enable-printer',
  412.             'share-printer',
  413.             'create-class',
  414.             'set-default-printer',
  415.             None,
  416.             'add-to-group',
  417.             'view-print-queue']:
  418.             if not action_name:
  419.                 item = gtk.SeparatorMenuItem()
  420.             else:
  421.                 action = printer_manager_action_group.get_action(action_name)
  422.                 item = action.create_menu_item()
  423.             item.show()
  424.             self.printer_context_menu.append(item)
  425.         
  426.         self.printer_menubar_item.set_submenu(self.printer_context_menu)
  427.         self.jobviewers = []
  428.         for combobox in [
  429.             self.cmbPStartBanner,
  430.             self.cmbPEndBanner,
  431.             self.cmbPErrorPolicy,
  432.             self.cmbPOperationPolicy]:
  433.             cell = gtk.CellRendererText()
  434.             combobox.clear()
  435.             combobox.pack_start(cell, True)
  436.             combobox.add_attribute(cell, 'text', 0)
  437.         
  438.         btn = self.btnRefreshMarkerLevels
  439.         btn.connect('clicked', self.on_btnRefreshMarkerLevels_clicked)
  440.         column = gtk.TreeViewColumn(_('Message'))
  441.         icon = gtk.CellRendererPixbuf()
  442.         column.pack_start(icon, False)
  443.         text = gtk.CellRendererText()
  444.         column.pack_start(text, False)
  445.         column.set_cell_data_func(icon, self.set_printer_state_reason_icon)
  446.         column.set_cell_data_func(text, self.set_printer_state_reason_text)
  447.         column.set_resizable(True)
  448.         self.tvPrinterStateReasons.append_column(column)
  449.         selection = self.tvPrinterStateReasons.get_selection()
  450.         selection.set_mode(gtk.SELECTION_NONE)
  451.         store = gtk.ListStore(int, str)
  452.         self.tvPrinterStateReasons.set_model(store)
  453.         self.newPrinterGUI = np = NewPrinterGUI(self)
  454.         np.NewPrinterWindow.set_transient_for(self.PrintersWindow)
  455.         self.AboutDialog.set_program_name(domain)
  456.         self.AboutDialog.set_version(config.VERSION)
  457.         self.AboutDialog.set_icon_name('printer')
  458.         
  459.         class UnobtrusiveButton(gtk.Button):
  460.             
  461.             def __init__(self, **args):
  462.                 gtk.Button.__init__(self, **args)
  463.                 self.set_relief(gtk.RELIEF_NONE)
  464.                 label = self.get_child()
  465.                 text = label.get_text()
  466.                 label.set_use_markup(True)
  467.                 label.set_markup('<span size="small" ' + 'underline="single" ' + 'color="#0000ee">%s</span>' % text)
  468.  
  469.  
  470.         problems = UnobtrusiveButton(label = _('Problems?'))
  471.         self.hboxServerBrowse.pack_end(problems, False, False, 0)
  472.         problems.connect('clicked', self.on_problems_button_clicked)
  473.         problems.show()
  474.         self.static_tabs = 3
  475.         gtk_label_autowrap.set_autowrap(self.PrintersWindow)
  476.         
  477.         try:
  478.             self.cups = authconn.Connection(self.PrintersWindow)
  479.         except RuntimeError:
  480.             self.cups = None
  481.  
  482.         self.status_context_id = self.statusbarMain.get_context_id('Connection')
  483.         self.setConnected()
  484.         self.setup_toolbar_for_search_entry()
  485.         self.current_filter_text = ''
  486.         self.current_filter_mode = 'filter-name'
  487.         self.groups_pane = GroupsPane()
  488.         self.current_groups_pane_item = self.groups_pane.get_selected_item()
  489.         self.groups_pane.connect('item-activated', self.on_groups_pane_item_activated)
  490.         self.groups_pane.connect('items-changed', self.on_groups_pane_items_changed)
  491.         self.PrintersWindow.add_accel_group(self.groups_pane.ui_manager.get_accel_group())
  492.         self.view_area_hpaned = gtk.HPaned()
  493.         self.view_area_hpaned.add1(self.groups_pane)
  494.         self.groups_pane_visible = False
  495.         if self.groups_pane.n_groups() > 0:
  496.             self.view_groups.set_active(True)
  497.         
  498.         self.group_menubar_item.set_submenu(self.groups_pane.groups_menu)
  499.         self.add_to_group_menu = gtk.Menu()
  500.         self.update_add_to_group_menu()
  501.         action = printer_manager_action_group.get_action('add-to-group')
  502.         for proxy in action.get_proxies():
  503.             if isinstance(proxy, gtk.MenuItem):
  504.                 item = proxy
  505.                 break
  506.                 continue
  507.         
  508.         item.set_submenu(self.add_to_group_menu)
  509.         menu = gtk.Menu()
  510.         for action_name in [
  511.             'filter-name',
  512.             'filter-description',
  513.             'filter-location',
  514.             'filter-manufacturer',
  515.             None,
  516.             'save-as-group',
  517.             'save-as-search-group']:
  518.             if not action_name:
  519.                 item = gtk.SeparatorMenuItem()
  520.             else:
  521.                 action = printer_manager_action_group.get_action(action_name)
  522.                 item = action.create_menu_item()
  523.             menu.append(item)
  524.         
  525.         menu.show_all()
  526.         self.search_entry.set_drop_down_menu(menu)
  527.         self.mainlist = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING)
  528.         self.dests_iconview.set_model(self.mainlist)
  529.         self.dests_iconview.set_column_spacing(30)
  530.         self.dests_iconview.set_row_spacing(20)
  531.         self.dests_iconview.set_pixbuf_column(1)
  532.         self.dests_iconview.set_text_column(2)
  533.         self.dests_iconview.set_tooltip_column(3)
  534.         self.dests_iconview.set_has_tooltip(True)
  535.         self.dests_iconview.connect('key-press-event', self.dests_iconview_key_press_event)
  536.         self.dests_iconview.connect('item-activated', self.dests_iconview_item_activated)
  537.         self.dests_iconview.connect('selection-changed', self.dests_iconview_selection_changed)
  538.         self.dests_iconview.connect('button-press-event', self.dests_iconview_button_press_event)
  539.         self.dests_iconview.connect('popup-menu', self.dests_iconview_popup_menu)
  540.         self.dests_iconview_selection_changed(self.dests_iconview)
  541.         self.dests_iconview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [
  542.             ('queue', 0, 0)], gtk.gdk.ACTION_COPY)
  543.         self.dests_iconview.connect('drag-data-get', self.dests_iconview_drag_data_get)
  544.         m = gtk.SELECTION_MULTIPLE
  545.         s = gtk.SELECTION_SINGLE
  546.         for name, treeview, selection_mode in ((_('Members of this class'), self.tvClassMembers, m), (_('Others'), self.tvClassNotMembers, m), (_('Members of this class'), np.tvNCMembers, m), (_('Others'), np.tvNCNotMembers, m), (_('Devices'), np.tvNPDevices, s), (_('Connections'), np.tvNPDeviceURIs, s), (_('Makes'), np.tvNPMakes, s), (_('Models'), np.tvNPModels, s), (_('Drivers'), np.tvNPDrivers, s), (_('Downloadable Drivers'), np.tvNPDownloadableDrivers, s), (_('Users'), self.tvPUsers, m)):
  547.             model = gtk.ListStore(str)
  548.             cell = gtk.CellRendererText()
  549.             column = gtk.TreeViewColumn(name, cell, text = 0)
  550.             treeview.set_model(model)
  551.             treeview.append_column(column)
  552.             treeview.get_selection().set_mode(selection_mode)
  553.         
  554.         self.ServerSettingsDialog.connect('response', self.server_settings_response)
  555.         self.PrinterPropertiesDialog.connect('response', self.printer_properties_response)
  556.         col = gtk.TreeViewColumn('', gtk.CellRendererText(), markup = 0)
  557.         self.tvPrinterProperties.append_column(col)
  558.         sel = self.tvPrinterProperties.get_selection()
  559.         sel.connect('changed', self.on_tvPrinterProperties_selection_changed)
  560.         sel.set_mode(gtk.SELECTION_SINGLE)
  561.         opts = [
  562.             options.OptionAlwaysShown('copies', int, 1, self.sbJOCopies, self.btnJOResetCopies),
  563.             options.OptionAlwaysShownSpecial('orientation-requested', int, 3, self.cmbJOOrientationRequested, self.btnJOResetOrientationRequested, combobox_map = [
  564.                 3,
  565.                 4,
  566.                 5,
  567.                 6], special_choice = _('Automatic rotation')),
  568.             options.OptionAlwaysShown('fitplot', bool, False, self.cbJOFitplot, self.btnJOResetFitplot),
  569.             options.OptionAlwaysShown('number-up', int, 1, self.cmbJONumberUp, self.btnJOResetNumberUp, combobox_map = [
  570.                 1,
  571.                 2,
  572.                 4,
  573.                 6,
  574.                 9,
  575.                 16]),
  576.             options.OptionAlwaysShown('number-up-layout', str, 'lrtb', self.cmbJONumberUpLayout, self.btnJOResetNumberUpLayout, combobox_map = [
  577.                 'lrtb',
  578.                 'lrbt',
  579.                 'rltb',
  580.                 'rlbt',
  581.                 'tblr',
  582.                 'tbrl',
  583.                 'btlr',
  584.                 'btrl']),
  585.             options.OptionAlwaysShown('brightness', int, 100, self.sbJOBrightness, self.btnJOResetBrightness),
  586.             options.OptionAlwaysShown('finishings', int, 3, self.cmbJOFinishings, self.btnJOResetFinishings, combobox_map = [
  587.                 3,
  588.                 4,
  589.                 5,
  590.                 6,
  591.                 7,
  592.                 8,
  593.                 9,
  594.                 10,
  595.                 11,
  596.                 12,
  597.                 13,
  598.                 14,
  599.                 20,
  600.                 21,
  601.                 22,
  602.                 23,
  603.                 24,
  604.                 25,
  605.                 26,
  606.                 27,
  607.                 28,
  608.                 29,
  609.                 30,
  610.                 31,
  611.                 50,
  612.                 51,
  613.                 52,
  614.                 53], use_supported = True),
  615.             options.OptionAlwaysShown('job-priority', int, 50, self.sbJOJobPriority, self.btnJOResetJobPriority),
  616.             options.OptionAlwaysShown('media', str, 'A4', self.cmbJOMedia, self.btnJOResetMedia, use_supported = True),
  617.             options.OptionAlwaysShown('sides', str, 'one-sided', self.cmbJOSides, self.btnJOResetSides, combobox_map = [
  618.                 'one-sided',
  619.                 'two-sided-long-edge',
  620.                 'two-sided-short-edge']),
  621.             options.OptionAlwaysShown('job-hold-until', str, 'no-hold', self.cmbJOHoldUntil, self.btnJOResetHoldUntil, use_supported = True),
  622.             options.OptionAlwaysShown('mirror', bool, False, self.cbJOMirror, self.btnJOResetMirror),
  623.             options.OptionAlwaysShown('scaling', int, 100, self.sbJOScaling, self.btnJOResetScaling),
  624.             options.OptionAlwaysShown('saturation', int, 100, self.sbJOSaturation, self.btnJOResetSaturation),
  625.             options.OptionAlwaysShown('hue', int, 0, self.sbJOHue, self.btnJOResetHue),
  626.             options.OptionAlwaysShown('gamma', int, 1000, self.sbJOGamma, self.btnJOResetGamma),
  627.             options.OptionAlwaysShown('cpi', float, 10, self.sbJOCpi, self.btnJOResetCpi),
  628.             options.OptionAlwaysShown('lpi', float, 6, self.sbJOLpi, self.btnJOResetLpi),
  629.             options.OptionAlwaysShown('page-left', int, 0, self.sbJOPageLeft, self.btnJOResetPageLeft),
  630.             options.OptionAlwaysShown('page-right', int, 0, self.sbJOPageRight, self.btnJOResetPageRight),
  631.             options.OptionAlwaysShown('page-top', int, 0, self.sbJOPageTop, self.btnJOResetPageTop),
  632.             options.OptionAlwaysShown('page-bottom', int, 0, self.sbJOPageBottom, self.btnJOResetPageBottom),
  633.             options.OptionAlwaysShown('prettyprint', bool, False, self.cbJOPrettyPrint, self.btnJOResetPrettyPrint),
  634.             options.OptionAlwaysShown('wrap', bool, False, self.cbJOWrap, self.btnJOResetWrap),
  635.             options.OptionAlwaysShown('columns', int, 1, self.sbJOColumns, self.btnJOResetColumns)]
  636.         self.job_options_widgets = { }
  637.         self.job_options_buttons = { }
  638.         for option in opts:
  639.             self.job_options_widgets[option.widget] = option
  640.             self.job_options_buttons[option.button] = option
  641.         
  642.         self.monitor = monitor.Monitor(self, monitor_jobs = False)
  643.         
  644.         try:
  645.             self.populateList()
  646.         except cups.HTTPError:
  647.             (s,) = None
  648.             self.cups = None
  649.             self.setConnected()
  650.             self.populateList()
  651.             show_HTTP_Error(s, self.PrintersWindow)
  652.  
  653.         if len(self.printers) > 3:
  654.             self.PrintersWindow.set_default_size(550, 400)
  655.         
  656.         self.PrintersWindow.show()
  657.         if setup_printer:
  658.             self.device_uri = setup_printer
  659.             self.devid = devid
  660.             self.ppd = None
  661.             
  662.             try:
  663.                 self.on_autodetected_printer_without_driver(None)
  664.             except RuntimeError:
  665.                 pass
  666.             except:
  667.                 None<EXCEPTION MATCH>RuntimeError
  668.             
  669.  
  670.         None<EXCEPTION MATCH>RuntimeError
  671.         if configure_printer:
  672.             
  673.             try:
  674.                 self.display_properties_dialog_for(configure_printer)
  675.                 if print_test_page:
  676.                     self.btnPrintTestPage.clicked()
  677.                 
  678.                 if change_ppd:
  679.                     self.btnChangePPD.clicked()
  680.             except RuntimeError:
  681.                 pass
  682.             except:
  683.                 None<EXCEPTION MATCH>RuntimeError
  684.             
  685.  
  686.         None<EXCEPTION MATCH>RuntimeError
  687.  
  688.     
  689.     def display_properties_dialog_for(self, queue):
  690.         model = self.dests_iconview.get_model()
  691.         iter = model.get_iter_first()
  692.         while iter != None:
  693.             name = unicode(model.get_value(iter, 2))
  694.             if name == queue:
  695.                 path = model.get_path(iter)
  696.                 self.dests_iconview.scroll_to_path(path, True, 0.5, 0.5)
  697.                 self.dests_iconview.set_cursor(path)
  698.                 self.dests_iconview.item_activated(path)
  699.                 break
  700.             
  701.             iter = model.iter_next(iter)
  702.         if iter == None:
  703.             raise RuntimeError
  704.         iter == None
  705.  
  706.     
  707.     def setup_toolbar_for_search_entry(self):
  708.         separator = gtk.SeparatorToolItem()
  709.         separator.set_draw(False)
  710.         self.toolbar.insert(separator, -1)
  711.         self.toolbar.child_set_property(separator, 'expand', True)
  712.         self.search_entry = ToolbarSearchEntry()
  713.         self.search_entry.connect('search', self.on_search_entry_search)
  714.         tool_item = gtk.ToolItem()
  715.         tool_item.add(self.search_entry)
  716.         self.toolbar.insert(tool_item, -1)
  717.         self.toolbar.show_all()
  718.  
  719.     
  720.     def on_search_entry_search(self, UNUSED, text):
  721.         if not text or True:
  722.             pass
  723.         self.ui_manager.get_action('/save-as-group').set_sensitive(False)
  724.         if not text or True:
  725.             pass
  726.         self.ui_manager.get_action('/save-as-search-group').set_sensitive(False)
  727.         self.current_filter_text = text
  728.         self.populateList()
  729.  
  730.     
  731.     def on_groups_pane_item_activated(self, UNUSED, item):
  732.         self.search_entry.clear()
  733.         if isinstance(item, SavedSearchGroupItem):
  734.             crit = item.criteria[0]
  735.             if crit.subject == SearchCriterion.SUBJECT_NAME:
  736.                 self.ui_manager.get_action('/filter-name').activate()
  737.             elif crit.subject == SearchCriterion.SUBJECT_DESC:
  738.                 self.ui_manager.get_action('/filter-description').activate()
  739.             elif crit.subject == SearchCriterion.SUBJECT_LOCATION:
  740.                 self.ui_manager.get_action('/filter-location').activate()
  741.             elif crit.subject == SearchCriterion.SUBJECT_MANUF:
  742.                 self.ui_manager.get_action('/filter-manufacturer').activate()
  743.             else:
  744.                 nonfatalException()
  745.             self.search_entry.set_text(crit.value)
  746.         
  747.         self.current_groups_pane_item = item
  748.         self.populateList()
  749.  
  750.     
  751.     def on_add_to_group_menu_item_activate(self, menuitem, group):
  752.         group.add_queues(self.groups_pane.currently_selected_queues)
  753.  
  754.     
  755.     def update_add_to_group_menu(self):
  756.         for child in self.add_to_group_menu.get_children():
  757.             self.add_to_group_menu.remove(child)
  758.         
  759.         static_groups = self.groups_pane.get_static_groups()
  760.         for group in static_groups:
  761.             item = gtk.MenuItem(group.name, False)
  762.             item.connect('activate', self.on_add_to_group_menu_item_activate, group)
  763.             self.add_to_group_menu.append(item)
  764.         
  765.         if len(static_groups) > 0:
  766.             item = gtk.SeparatorMenuItem()
  767.             self.add_to_group_menu.append(item)
  768.         
  769.         action = self.groups_pane.ui_manager.get_action('/new-group-from-selection')
  770.         item = action.create_menu_item()
  771.         self.add_to_group_menu.append(item)
  772.         self.add_to_group_menu.show_all()
  773.  
  774.     
  775.     def on_groups_pane_items_changed(self, UNUSED):
  776.         if not self.groups_pane_visible:
  777.             self.view_groups.set_active(True)
  778.         
  779.         self.update_add_to_group_menu()
  780.  
  781.     
  782.     def on_filter_criterion_changed(self, UNUSED, selected_action):
  783.         self.current_filter_mode = selected_action.get_name()
  784.         self.populateList()
  785.  
  786.     
  787.     def dests_iconview_item_activated(self, iconview, path):
  788.         model = iconview.get_model()
  789.         iter = model.get_iter(path)
  790.         name = unicode(model.get_value(iter, 2))
  791.         object = model.get_value(iter, 0)
  792.         
  793.         try:
  794.             self.fillPrinterTab(name)
  795.         except cups.IPPError:
  796.             (e, m) = None
  797.             show_IPP_Error(e, m, self.PrintersWindow)
  798.             if e == cups.IPP_SERVICE_UNAVAILABLE:
  799.                 self.cups = None
  800.                 self.setConnected()
  801.                 self.populateList()
  802.             
  803.             return None
  804.             except RuntimeError:
  805.                 return None
  806.             else:
  807.                 self.PrinterPropertiesDialog.set_transient_for(self.PrintersWindow)
  808.                 for button in [
  809.                     self.btnPrinterPropertiesCancel,
  810.                     self.btnPrinterPropertiesOK,
  811.                     self.btnPrinterPropertiesApply]:
  812.                     if object.discovered:
  813.                         button.hide()
  814.                         continue
  815.                     button.show()
  816.                 
  817.  
  818.         if object.discovered:
  819.             self.btnPrinterPropertiesClose.show()
  820.         else:
  821.             self.btnPrinterPropertiesClose.hide()
  822.         self.setDataButtonState()
  823.         treeview = self.tvPrinterProperties
  824.         treeview.set_cursor((0,))
  825.         host = CUPS_server_hostname()
  826.         self.PrinterPropertiesDialog.set_title(_("Printer Properties - '%s' on %s") % (name, host))
  827.         self.PrinterPropertiesDialog.set_focus_on_map(self.focus_on_map)
  828.         self.PrinterPropertiesDialog.show()
  829.  
  830.     
  831.     def printer_properties_response(self, dialog, response):
  832.         if response == gtk.RESPONSE_REJECT:
  833.             message = _('There are conflicting options.\nChanges can only be applied after\nthese conflicts are resolved.')
  834.             message += '\n\n'
  835.             for option in self.conflicts:
  836.                 message += option.option.text + '\n'
  837.             
  838.             dialog = gtk.MessageDialog(self.PrinterPropertiesDialog, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, message)
  839.             dialog.run()
  840.             dialog.destroy()
  841.             return None
  842.         if response == gtk.RESPONSE_OK or response == gtk.RESPONSE_APPLY:
  843.             success = self.save_printer(self.printer)
  844.         
  845.         if response == gtk.RESPONSE_APPLY:
  846.             
  847.             try:
  848.                 self.fillPrinterTab(self.printer.name)
  849.             except:
  850.                 pass
  851.  
  852.             self.setDataButtonState()
  853.         
  854.         if response == gtk.RESPONSE_OK or not success or response == gtk.RESPONSE_CANCEL:
  855.             self.printer = None
  856.             dialog.hide()
  857.         
  858.  
  859.     
  860.     def dests_iconview_selection_changed(self, iconview):
  861.         self.updating_widgets = True
  862.         paths = iconview.get_selected_items()
  863.         any_disabled = False
  864.         any_enabled = False
  865.         any_discovered = False
  866.         any_shared = False
  867.         any_unshared = False
  868.         self.groups_pane.currently_selected_queues = []
  869.         model = iconview.get_model()
  870.         for path in paths:
  871.             iter = model.get_iter(path)
  872.             object = model.get_value(iter, 0)
  873.             name = unicode(model.get_value(iter, 2))
  874.             self.groups_pane.currently_selected_queues.append(name)
  875.             if object.discovered:
  876.                 any_discovered = True
  877.             
  878.             if object.enabled:
  879.                 any_enabled = True
  880.             else:
  881.                 any_disabled = True
  882.             if object.is_shared:
  883.                 any_shared = True
  884.                 continue
  885.             any_unshared = True
  886.         
  887.         n = len(paths)
  888.         self.groups_pane.ui_manager.get_action('/new-group-from-selection').set_sensitive(n > 0)
  889.         self.ui_manager.get_action('/edit-printer').set_sensitive(n == 1)
  890.         self.ui_manager.get_action('/copy-printer').set_sensitive(n == 1)
  891.         if n == 1:
  892.             pass
  893.         self.ui_manager.get_action('/rename-printer').set_sensitive(not any_discovered)
  894.         userdef = userdefault.UserDefaultPrinter().get()
  895.         if (n != 1 or userdef == None) and self.default_printer == name:
  896.             set_default_sensitivity = False
  897.         else:
  898.             set_default_sensitivity = True
  899.         self.ui_manager.get_action('/set-default-printer').set_sensitive(set_default_sensitivity)
  900.         action = self.ui_manager.get_action('/enable-printer')
  901.         if n > 0:
  902.             pass
  903.         action.set_sensitive(not any_discovered)
  904.         for widget in action.get_proxies():
  905.             if isinstance(widget, gtk.CheckMenuItem):
  906.                 if n > 1 and any_enabled:
  907.                     pass
  908.                 widget.set_inconsistent(any_disabled)
  909.                 continue
  910.         
  911.         if not any_discovered:
  912.             pass
  913.         action.set_active(not any_disabled)
  914.         action = self.ui_manager.get_action('/share-printer')
  915.         if n > 0:
  916.             pass
  917.         action.set_sensitive(not any_discovered)
  918.         for widget in action.get_proxies():
  919.             if isinstance(widget, gtk.CheckMenuItem):
  920.                 if n > 1 and any_shared:
  921.                     pass
  922.                 widget.set_inconsistent(any_unshared)
  923.                 continue
  924.         
  925.         if not any_discovered:
  926.             pass
  927.         action.set_active(not any_unshared)
  928.         if n > 0:
  929.             pass
  930.         self.ui_manager.get_action('/delete-printer').set_sensitive(not any_discovered)
  931.         self.ui_manager.get_action('/create-class').set_sensitive(n > 1)
  932.         self.ui_manager.get_action('/add-to-group').set_sensitive(n > 0)
  933.         self.updating_widgets = False
  934.  
  935.     
  936.     def dests_iconview_popup_menu(self, iconview):
  937.         self.printer_context_menu.popup(None, None, None, 0, 0x0L)
  938.  
  939.     
  940.     def dests_iconview_button_press_event(self, iconview, event):
  941.         if event.button > 1:
  942.             click_path = iconview.get_path_at_pos(int(event.x), int(event.y))
  943.             paths = iconview.get_selected_items()
  944.             if click_path == None:
  945.                 iconview.unselect_all()
  946.             elif click_path not in paths:
  947.                 iconview.unselect_all()
  948.                 iconview.select_path(click_path)
  949.                 cells = iconview.get_cells()
  950.                 for cell in cells:
  951.                     if type(cell) == gtk.CellRendererText:
  952.                         break
  953.                         continue
  954.                 
  955.                 iconview.set_cursor(click_path, cell)
  956.             
  957.             self.printer_context_menu.popup(None, None, None, event.button, event.time)
  958.         
  959.         return False
  960.  
  961.     
  962.     def dests_iconview_key_press_event(self, iconview, event):
  963.         modifiers = gtk.accelerator_get_default_mod_mask()
  964.         if (event.keyval == gtk.keysyms.BackSpace and event.keyval == gtk.keysyms.Delete or event.keyval == gtk.keysyms.KP_Delete) and event.state & modifiers == 0:
  965.             self.ui_manager.get_action('/delete-printer').activate()
  966.             return True
  967.         if event.keyval == gtk.keysyms.F2 and event.state & modifiers == 0:
  968.             self.ui_manager.get_action('/rename-printer').activate()
  969.             return True
  970.         return False
  971.  
  972.     
  973.     def dests_iconview_drag_data_get(self, iconview, context, selection_data, info, timestamp):
  974.         if info == 0:
  975.             model = iconview.get_model()
  976.             paths = iconview.get_selected_items()
  977.             selected_printer_names = ''
  978.             for path in paths:
  979.                 selected_printer_names += model.get_value(model.get_iter(path), 2) + '\n'
  980.             
  981.             if len(selected_printer_names) > 0:
  982.                 selection_data.set('queue', 8, selected_printer_names)
  983.             
  984.         else:
  985.             nonfatalException()
  986.  
  987.     
  988.     def on_server_settings_activate(self, menuitem):
  989.         
  990.         try:
  991.             self.fillServerTab()
  992.         except cups.IPPError:
  993.             return None
  994.  
  995.         self.ServerSettingsDialog.set_transient_for(self.PrintersWindow)
  996.         self.ServerSettingsDialog.show()
  997.  
  998.     
  999.     def server_settings_response(self, dialog, response):
  1000.         if response == gtk.RESPONSE_OK:
  1001.             if not self.save_serversettings():
  1002.                 dialog.hide()
  1003.             
  1004.         elif response == gtk.RESPONSE_YES:
  1005.             
  1006.             try:
  1007.                 AdvancedServerSettingsDialog(self.cups, dialog, self.on_adv_server_settings_apply)
  1008.             return None
  1009.  
  1010.         else:
  1011.             dialog.hide()
  1012.  
  1013.     
  1014.     def on_adv_server_settings_apply(self):
  1015.         
  1016.         try:
  1017.             self.fillServerTab()
  1018.         except cups.IPPError:
  1019.             self.ServerSettingsDialog.hide()
  1020.  
  1021.  
  1022.     
  1023.     def busy(self, win = None):
  1024.         
  1025.         try:
  1026.             if not win:
  1027.                 win = self.PrintersWindow
  1028.             
  1029.             gdkwin = win.window
  1030.             if gdkwin:
  1031.                 gdkwin.set_cursor(busy_cursor)
  1032.                 while gtk.events_pending():
  1033.                     gtk.main_iteration()
  1034.         except:
  1035.             nonfatalException()
  1036.  
  1037.  
  1038.     
  1039.     def ready(self, win = None):
  1040.         
  1041.         try:
  1042.             if not win:
  1043.                 win = self.PrintersWindow
  1044.             
  1045.             gdkwin = win.window
  1046.             if gdkwin:
  1047.                 gdkwin.set_cursor(None)
  1048.                 while gtk.events_pending():
  1049.                     gtk.main_iteration()
  1050.         except:
  1051.             nonfatalException()
  1052.  
  1053.  
  1054.     
  1055.     def setConnected(self):
  1056.         connected = bool(self.cups)
  1057.         host = CUPS_server_hostname()
  1058.         self.PrintersWindow.set_title(_('Printer configuration - %s') % host)
  1059.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  1060.         if connected:
  1061.             status_msg = _('Connected to %s') % host
  1062.         else:
  1063.             status_msg = _('Not connected')
  1064.         self.statusbarMain.push(self.status_context_id, status_msg)
  1065.         for widget in (self.btnNew, self.new_printer, self.new_class, self.chkServerBrowse, self.chkServerShare, self.chkServerRemoteAdmin, self.chkServerAllowCancelAll, self.chkServerLogDebug, self.server_settings_menu_entry):
  1066.             widget.set_sensitive(connected)
  1067.         
  1068.         sharing = self.chkServerShare.get_active()
  1069.         self.chkServerShareAny.set_sensitive(sharing)
  1070.         
  1071.         try:
  1072.             del self.server_settings
  1073.         except:
  1074.             pass
  1075.  
  1076.  
  1077.     
  1078.     def getServers(self):
  1079.         self.servers.discard(None)
  1080.         known_servers = list(self.servers)
  1081.         known_servers.sort()
  1082.         return known_servers
  1083.  
  1084.     
  1085.     def populateList(self, prompt_allowed = True):
  1086.         selected_printers = set()
  1087.         paths = self.dests_iconview.get_selected_items()
  1088.         model = self.dests_iconview.get_model()
  1089.         for path in paths:
  1090.             iter = model.get_iter(path)
  1091.             name = unicode(model.get_value(iter, 2))
  1092.             selected_printers.add(name)
  1093.         
  1094.         if self.cups:
  1095.             self.cups._set_prompt_allowed(prompt_allowed)
  1096.             self.cups._begin_operation(_('obtaining queue details'))
  1097.             
  1098.             try:
  1099.                 self.printers = cupshelpers.getPrinters(self.cups)
  1100.                 self.default_printer = self.cups.getDefault()
  1101.             except cups.IPPError:
  1102.                 (e, m) = None
  1103.                 show_IPP_Error(e, m, self.PrintersWindow)
  1104.                 self.printers = { }
  1105.                 self.default_printer = None
  1106.  
  1107.             self.cups._end_operation()
  1108.             self.cups._set_prompt_allowed(True)
  1109.         else:
  1110.             self.printers = { }
  1111.             self.default_printer = None
  1112.         for name, printer in self.printers.iteritems():
  1113.             self.servers.add(printer.getServer())
  1114.         
  1115.         userdef = userdefault.UserDefaultPrinter().get()
  1116.         local_printers = []
  1117.         local_classes = []
  1118.         remote_printers = []
  1119.         remote_classes = []
  1120.         if isinstance(self.current_groups_pane_item, AllPrintersItem) or isinstance(self.current_groups_pane_item, SavedSearchGroupItem):
  1121.             delete_action = self.ui_manager.get_action('/delete-printer')
  1122.             delete_action.set_properties(label = None)
  1123.             printers_set = self.printers
  1124.         elif isinstance(self.current_groups_pane_item, FavouritesItem):
  1125.             printers_set = { }
  1126.         elif isinstance(self.current_groups_pane_item, StaticGroupItem):
  1127.             delete_action = self.ui_manager.get_action('/delete-printer')
  1128.             delete_action.set_properties(label = _('Remove from Group'))
  1129.             printers_set = { }
  1130.             deleted_printers = []
  1131.             for printer_name in self.current_groups_pane_item.printer_queues:
  1132.                 
  1133.                 try:
  1134.                     printer = self.printers[printer_name]
  1135.                     printers_set[printer_name] = printer
  1136.                 continue
  1137.                 except KeyError:
  1138.                     deleted_printers.append(printer_name)
  1139.                     continue
  1140.                 
  1141.  
  1142.             
  1143.             self.current_groups_pane_item.remove_queues(deleted_printers)
  1144.         else:
  1145.             printers_set = self.printers
  1146.             nonfatalException()
  1147.         if len(self.current_filter_text) > 0:
  1148.             printers_subset = { }
  1149.             pattern = re.compile(self.current_filter_text, re.I)
  1150.             if self.current_filter_mode == 'filter-name':
  1151.                 for name in printers_set.keys():
  1152.                     if pattern.search(name) != None:
  1153.                         printers_subset[name] = printers_set[name]
  1154.                         continue
  1155.                 
  1156.             elif self.current_filter_mode == 'filter-description':
  1157.                 for name, printer in printers_set.iteritems():
  1158.                     if pattern.search(printer.info) != None:
  1159.                         printers_subset[name] = printers_set[name]
  1160.                         continue
  1161.                 
  1162.             elif self.current_filter_mode == 'filter-location':
  1163.                 for name, printer in printers_set.iteritems():
  1164.                     if pattern.search(printer.location) != None:
  1165.                         printers_subset[name] = printers_set[name]
  1166.                         continue
  1167.                 
  1168.             elif self.current_filter_mode == 'filter-manufacturer':
  1169.                 for name, printer in printers_set.iteritems():
  1170.                     if pattern.search(printer.make_and_model) != None:
  1171.                         printers_subset[name] = printers_set[name]
  1172.                         continue
  1173.                 
  1174.             else:
  1175.                 nonfatalException()
  1176.             printers_set = printers_subset
  1177.         
  1178.         if not self.view_discovered_printers.get_active():
  1179.             printers_subset = { }
  1180.             for name, printer in printers_set.iteritems():
  1181.                 if not printer.discovered:
  1182.                     printers_subset[name] = printer
  1183.                     continue
  1184.             
  1185.             printers_set = printers_subset
  1186.         
  1187.         for name, printer in printers_set.iteritems():
  1188.             if printer.remote:
  1189.                 if printer.is_class:
  1190.                     remote_classes.append(name)
  1191.                 else:
  1192.                     remote_printers.append(name)
  1193.             printer.is_class
  1194.             if printer.is_class:
  1195.                 local_classes.append(name)
  1196.                 continue
  1197.             local_printers.append(name)
  1198.         
  1199.         local_printers.sort()
  1200.         local_classes.sort()
  1201.         remote_printers.sort()
  1202.         remote_classes.sort()
  1203.         self.mainlist.clear()
  1204.         PRINTER_TYPE = {
  1205.             'discovered-printer': (_('Network printer (discovered)'), 'i-network-printer'),
  1206.             'discovered-class': (_('Network class (discovered)'), 'i-network-printer'),
  1207.             'local-printer': (_('Printer'), 'gnome-dev-printer'),
  1208.             'local-fax': (_('Fax'), 'gnome-dev-printer'),
  1209.             'local-class': (_('Class'), 'gnome-dev-printer'),
  1210.             'ipp-printer': (_('Network printer'), 'i-network-printer'),
  1211.             'smb-printer': (_('Network print share'), 'gnome-dev-printer'),
  1212.             'network-printer': (_('Network printer'), 'i-network-printer') }
  1213.         theme = gtk.icon_theme_get_default()
  1214.         for printers in (local_printers, local_classes, remote_printers, remote_classes):
  1215.             if not printers:
  1216.                 continue
  1217.             
  1218.             for name in printers:
  1219.                 type = 'local-printer'
  1220.                 object = printers_set[name]
  1221.                 if object.discovered:
  1222.                     if object.is_class:
  1223.                         type = 'discovered-class'
  1224.                     else:
  1225.                         type = 'discovered-printer'
  1226.                 elif object.is_class:
  1227.                     type = 'local-class'
  1228.                 else:
  1229.                     (scheme, rest) = urllib.splittype(object.device_uri)
  1230.                     if scheme == 'ipp':
  1231.                         type = 'ipp-printer'
  1232.                     elif scheme == 'smb':
  1233.                         type = 'smb-printer'
  1234.                     elif scheme == 'hpfax':
  1235.                         type = 'local-fax'
  1236.                     elif scheme in ('socket', 'lpd'):
  1237.                         type = 'network-printer'
  1238.                     
  1239.                 (tip, icon) = PRINTER_TYPE[type]
  1240.                 (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1241.                 
  1242.                 try:
  1243.                     pixbuf = theme.load_icon(icon, w, 0)
  1244.                 except gobject.GError:
  1245.                     pixbuf = None
  1246.                     for p in [
  1247.                         iconpath,
  1248.                         'icons/']:
  1249.                         
  1250.                         try:
  1251.                             pixbuf = gtk.gdk.pixbuf_new_from_file('%s%s.png' % (p, icon))
  1252.                         continue
  1253.                         except gobject.GError:
  1254.                             continue
  1255.                         
  1256.  
  1257.                     
  1258.                     if pixbuf == None:
  1259.                         
  1260.                         try:
  1261.                             pixbuf = theme.load_icon('printer', w, 0)
  1262.                         pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
  1263.                         pixbuf.fill(0)
  1264.  
  1265.                     
  1266.                 except:
  1267.                     None<EXCEPTION MATCH>gobject.GError
  1268.  
  1269.                 def_emblem = None
  1270.                 emblem = None
  1271.                 if name == self.default_printer:
  1272.                     def_emblem = 'emblem-default'
  1273.                 elif name == userdef:
  1274.                     def_emblem = 'emblem-favorite'
  1275.                 
  1276.                 if not emblem:
  1277.                     attrs = object.other_attributes
  1278.                     reasons = attrs.get('printer-state-reasons', [])
  1279.                     worst_reason = None
  1280.                     for reason in reasons:
  1281.                         if reason == 'none':
  1282.                             break
  1283.                         
  1284.                         if reason == 'paused':
  1285.                             emblem = gtk.STOCK_MEDIA_PAUSE
  1286.                             continue
  1287.                         
  1288.                         r = statereason.StateReason(object.name, reason)
  1289.                         if worst_reason == None:
  1290.                             worst_reason = r
  1291.                             continue
  1292.                         if r > worst_reason:
  1293.                             worst_reason = r
  1294.                             continue
  1295.                     
  1296.                     if worst_reason:
  1297.                         level = worst_reason.get_level()
  1298.                         emblem = worst_reason.LEVEL_ICON[level]
  1299.                     
  1300.                 
  1301.                 if not emblem and not (object.enabled):
  1302.                     emblem = gtk.STOCK_MEDIA_PAUSE
  1303.                 
  1304.                 if object.rejecting:
  1305.                     copy = pixbuf.copy()
  1306.                     copy.fill(0)
  1307.                     pixbuf.composite(copy, 0, 0, copy.get_width(), copy.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 127)
  1308.                     pixbuf = copy
  1309.                 
  1310.                 if def_emblem:
  1311.                     (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1312.                     default_emblem = theme.load_icon(def_emblem, w / 2, 0)
  1313.                     copy = pixbuf.copy()
  1314.                     default_emblem.composite(copy, 0, 0, copy.get_width(), copy.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
  1315.                     pixbuf = copy
  1316.                 
  1317.                 if emblem:
  1318.                     (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1319.                     other_emblem = theme.load_icon(emblem, w / 2, 0)
  1320.                     copy = pixbuf.copy()
  1321.                     other_emblem.composite(copy, 0, 0, copy.get_width(), copy.get_height(), copy.get_width() / 2, copy.get_height() / 2, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
  1322.                     pixbuf = copy
  1323.                 
  1324.                 self.mainlist.append(row = [
  1325.                     object,
  1326.                     pixbuf,
  1327.                     name,
  1328.                     tip])
  1329.             
  1330.         
  1331.         model = self.dests_iconview.get_model()
  1332.         
  1333.         def maybe_select(model, path, iter):
  1334.             name = unicode(model.get_value(iter, 2))
  1335.             if name in selected_printers:
  1336.                 self.dests_iconview.select_path(path)
  1337.             
  1338.  
  1339.         model.foreach(maybe_select)
  1340.         if self.printer != None and self.printer.name not in self.printers.keys():
  1341.             self.PrinterPropertiesDialog.response(gtk.RESPONSE_CANCEL)
  1342.         
  1343.  
  1344.     
  1345.     def on_connect_servername_changed(self, widget):
  1346.         self.btnConnect.set_sensitive(len(widget.get_active_text()) > 0)
  1347.  
  1348.     
  1349.     def on_connect_activate(self, widget):
  1350.         servers = self.getServers()
  1351.         if not self.printer or self.printer.getServer():
  1352.             pass
  1353.         current_server = cups.getServer()
  1354.         store = gtk.ListStore(gobject.TYPE_STRING)
  1355.         self.cmbServername.set_model(store)
  1356.         for server in servers:
  1357.             self.cmbServername.append_text(server)
  1358.         
  1359.         self.cmbServername.show()
  1360.         self.cmbServername.child.set_text(current_server)
  1361.         self.chkEncrypted.set_active(cups.getEncryption() == cups.HTTP_ENCRYPT_ALWAYS)
  1362.         self.cmbServername.child.set_activates_default(True)
  1363.         self.cmbServername.grab_focus()
  1364.         self.ConnectDialog.set_transient_for(self.PrintersWindow)
  1365.         response = self.ConnectDialog.run()
  1366.         self.ConnectDialog.hide()
  1367.         if response != gtk.RESPONSE_OK:
  1368.             return None
  1369.         if self.chkEncrypted.get_active():
  1370.             cups.setEncryption(cups.HTTP_ENCRYPT_ALWAYS)
  1371.         else:
  1372.             cups.setEncryption(cups.HTTP_ENCRYPT_IF_REQUESTED)
  1373.         self.connect_encrypt = cups.getEncryption()
  1374.         servername = self.cmbServername.child.get_text()
  1375.         self.lblConnecting.set_markup(_('<i>Opening connection to %s</i>') % servername)
  1376.         self.newPrinterGUI.dropPPDs()
  1377.         self.ConnectingDialog.set_transient_for(self.PrintersWindow)
  1378.         self.ConnectingDialog.show()
  1379.         gobject.timeout_add(40, self.update_connecting_pbar)
  1380.         self.connect_server = servername
  1381.         cups.setServer(self.connect_server)
  1382.         cups.setUser('')
  1383.         self.connect_user = cups.getUser()
  1384.         self.connect_thread = thread.start_new_thread(self.connect, (self.PrintersWindow,))
  1385.  
  1386.     
  1387.     def update_connecting_pbar(self):
  1388.         if not self.ConnectingDialog.get_property('visible'):
  1389.             return False
  1390.         self.pbarConnecting.pulse()
  1391.         return True
  1392.  
  1393.     
  1394.     def on_connectingdialog_delete(self, widget, event):
  1395.         self.on_cancel_connect_clicked(widget)
  1396.         return True
  1397.  
  1398.     
  1399.     def on_cancel_connect_clicked(self, widget):
  1400.         """
  1401.         Stop connection to new server
  1402.         (Doesn't really stop but sets flag for the connecting thread to
  1403.         ignore the connection)
  1404.         """
  1405.         self.connect_thread = None
  1406.         self.ConnectingDialog.hide()
  1407.  
  1408.     
  1409.     def connect(self, parent = None):
  1410.         '''
  1411.         Open a connection to a new server. Is executed in a separate thread!
  1412.         '''
  1413.         cups.setUser(self.connect_user)
  1414.         if self.connect_server[0] == '/':
  1415.             
  1416.             try:
  1417.                 connection = cups.Connection(host = self.connect_server, encryption = self.connect_encrypt)
  1418.                 del connection
  1419.             except RuntimeError:
  1420.                 cups.setServer('localhost')
  1421.             except:
  1422.                 None<EXCEPTION MATCH>RuntimeError
  1423.                 nonfatalException()
  1424.             
  1425.  
  1426.         None<EXCEPTION MATCH>RuntimeError
  1427.         
  1428.         try:
  1429.             connection = authconn.Connection(parent, host = self.connect_server, encryption = self.connect_encrypt)
  1430.             self.newPrinterGUI.dropPPDs()
  1431.         except RuntimeError:
  1432.             s = None
  1433.             if self.connect_thread != thread.get_ident():
  1434.                 return None
  1435.             gtk.gdk.threads_enter()
  1436.             self.ConnectingDialog.hide()
  1437.             show_IPP_Error(None, s, parent)
  1438.             gtk.gdk.threads_leave()
  1439.             return None
  1440.             self.connect_thread != thread.get_ident()
  1441.             except cups.IPPError:
  1442.                 (e, s) = None
  1443.                 if self.connect_thread != thread.get_ident():
  1444.                     return None
  1445.                 gtk.gdk.threads_enter()
  1446.                 self.ConnectingDialog.hide()
  1447.                 show_IPP_Error(e, s, parent)
  1448.                 gtk.gdk.threads_leave()
  1449.                 return None
  1450.                 self.connect_thread != thread.get_ident()
  1451.                 nonfatalException()
  1452.             
  1453.  
  1454.         if self.connect_thread != thread.get_ident():
  1455.             return None
  1456.         gtk.gdk.threads_enter()
  1457.         
  1458.         try:
  1459.             self.ConnectingDialog.hide()
  1460.             self.cups = connection
  1461.             self.setConnected()
  1462.             self.populateList()
  1463.         except cups.HTTPError:
  1464.             self.connect_thread != thread.get_ident()
  1465.             (s,) = self.connect_thread != thread.get_ident()
  1466.             None<EXCEPTION MATCH>cups.IPPError
  1467.             self.cups = None
  1468.             self.setConnected()
  1469.             self.populateList()
  1470.             show_HTTP_Error(s, parent)
  1471.         except:
  1472.             self.connect_thread != thread.get_ident()
  1473.             None<EXCEPTION MATCH>cups.IPPError
  1474.             nonfatalException()
  1475.  
  1476.         gtk.gdk.threads_leave()
  1477.  
  1478.     
  1479.     def reconnect(self):
  1480.         '''Reconnect to CUPS after the server has reloaded.'''
  1481.         attempt = 1
  1482.         while attempt <= 5:
  1483.             
  1484.             try:
  1485.                 time.sleep(1)
  1486.                 self.cups._connect()
  1487.             continue
  1488.             except RuntimeError:
  1489.                 attempt += 1
  1490.                 continue
  1491.             
  1492.  
  1493.             None<EXCEPTION MATCH>RuntimeError
  1494.  
  1495.     
  1496.     def on_btnCancelConnect_clicked(self, widget):
  1497.         '''Close Connect dialog'''
  1498.         self.ConnectWindow.hide()
  1499.  
  1500.     
  1501.     def on_btnRefresh_clicked(self, button):
  1502.         if self.cups == None:
  1503.             
  1504.             try:
  1505.                 self.cups = authconn.Connection(self.PrintersWindow)
  1506.             except RuntimeError:
  1507.                 pass
  1508.  
  1509.             self.setConnected()
  1510.         
  1511.         self.populateList()
  1512.  
  1513.     
  1514.     def on_printer_changed(self, widget):
  1515.         if isinstance(widget, gtk.CheckButton):
  1516.             value = widget.get_active()
  1517.         elif isinstance(widget, gtk.Entry):
  1518.             value = widget.get_text()
  1519.         elif isinstance(widget, gtk.RadioButton):
  1520.             value = widget.get_active()
  1521.         elif isinstance(widget, gtk.ComboBox):
  1522.             model = widget.get_model()
  1523.             iter = widget.get_active_iter()
  1524.             value = model.get_value(iter, 1)
  1525.         else:
  1526.             raise ValueError, 'Widget type not supported (yet)'
  1527.         p = isinstance(widget, gtk.CheckButton).printer
  1528.         old_values = {
  1529.             self.entPDescription: p.info,
  1530.             self.entPLocation: p.location,
  1531.             self.entPDevice: p.device_uri,
  1532.             self.chkPEnabled: p.enabled,
  1533.             self.chkPAccepting: not (p.rejecting),
  1534.             self.chkPShared: p.is_shared,
  1535.             self.cmbPStartBanner: p.job_sheet_start,
  1536.             self.cmbPEndBanner: p.job_sheet_end,
  1537.             self.cmbPErrorPolicy: p.error_policy,
  1538.             self.cmbPOperationPolicy: p.op_policy,
  1539.             self.rbtnPAllow: p.default_allow }
  1540.         old_value = old_values[widget]
  1541.         if old_value == value:
  1542.             self.changed.discard(widget)
  1543.         else:
  1544.             self.changed.add(widget)
  1545.         self.setDataButtonState()
  1546.  
  1547.     
  1548.     def option_changed(self, option):
  1549.         if option.is_changed():
  1550.             self.changed.add(option)
  1551.         else:
  1552.             self.changed.discard(option)
  1553.         if option.conflicts:
  1554.             self.conflicts.add(option)
  1555.         else:
  1556.             self.conflicts.discard(option)
  1557.         self.setDataButtonState()
  1558.         if self.option_manualfeed and self.option_inputslot and option == self.option_manualfeed:
  1559.             if option.get_current_value() == 'True':
  1560.                 self.option_inputslot.disable()
  1561.             else:
  1562.                 self.option_inputslot.enable()
  1563.         
  1564.  
  1565.     
  1566.     def getPUsers(self):
  1567.         '''return list of usernames from the GUI'''
  1568.         model = self.tvPUsers.get_model()
  1569.         result = []
  1570.         (model.foreach,)((lambda model, path, iter: result.append(model.get(iter, 0)[0])))
  1571.         result.sort()
  1572.         return result
  1573.  
  1574.     
  1575.     def setPUsers(self, users):
  1576.         '''write list of usernames inot the GUI'''
  1577.         model = self.tvPUsers.get_model()
  1578.         model.clear()
  1579.         for user in users:
  1580.             model.append((user,))
  1581.         
  1582.         self.on_entPUser_changed(self.entPUser)
  1583.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1584.  
  1585.     
  1586.     def checkPUsersChanged(self):
  1587.         '''check if users in GUI and printer are different
  1588.         and set self.changed'''
  1589.         if self.getPUsers() != self.printer.except_users:
  1590.             self.changed.add(self.tvPUsers)
  1591.         else:
  1592.             self.changed.discard(self.tvPUsers)
  1593.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1594.         self.setDataButtonState()
  1595.  
  1596.     
  1597.     def on_btnPAddUser_clicked(self, button):
  1598.         user = self.entPUser.get_text()
  1599.         if user:
  1600.             self.tvPUsers.get_model().insert(0, (user,))
  1601.             self.entPUser.set_text('')
  1602.         
  1603.         self.checkPUsersChanged()
  1604.  
  1605.     
  1606.     def on_btnPDelUser_clicked(self, button):
  1607.         (model, rows) = self.tvPUsers.get_selection().get_selected_rows()
  1608.         rows = [ gtk.TreeRowReference(model, row) for row in rows ]
  1609.         for row in rows:
  1610.             path = row.get_path()
  1611.             iter = model.get_iter(path)
  1612.             model.remove(iter)
  1613.         
  1614.         self.checkPUsersChanged()
  1615.  
  1616.     
  1617.     def on_entPUser_changed(self, widget):
  1618.         self.btnPAddUser.set_sensitive(bool(widget.get_text()))
  1619.  
  1620.     
  1621.     def on_tvPUsers_cursor_changed(self, widget):
  1622.         (model, rows) = widget.get_selection().get_selected_rows()
  1623.         self.btnPDelUser.set_sensitive(bool(rows))
  1624.  
  1625.     
  1626.     def on_job_option_reset(self, button):
  1627.         option = self.job_options_buttons[button]
  1628.         option.reset()
  1629.         if self.server_side_options.has_key(option.name):
  1630.             del self.server_side_options[option.name]
  1631.         
  1632.         if option.is_changed():
  1633.             self.changed.add(option)
  1634.         else:
  1635.             self.changed.discard(option)
  1636.         self.setDataButtonState()
  1637.  
  1638.     
  1639.     def on_job_option_changed(self, widget):
  1640.         if not self.printer:
  1641.             return None
  1642.         option = self.job_options_widgets[widget]
  1643.         option.changed()
  1644.         if option.is_changed():
  1645.             self.server_side_options[option.name] = option
  1646.             self.changed.add(option)
  1647.         elif self.server_side_options.has_key(option.name):
  1648.             del self.server_side_options[option.name]
  1649.         
  1650.         self.changed.discard(option)
  1651.         self.setDataButtonState()
  1652.  
  1653.     
  1654.     def draw_other_job_options(self, editable = True):
  1655.         n = len(self.other_job_options)
  1656.         if n == 0:
  1657.             self.tblJOOther.hide_all()
  1658.             return None
  1659.         self.tblJOOther.resize(n, 3)
  1660.         children = self.tblJOOther.get_children()
  1661.         for child in children:
  1662.             self.tblJOOther.remove(child)
  1663.         
  1664.         i = 0
  1665.         for opt in self.other_job_options:
  1666.             self.tblJOOther.attach(opt.label, 0, 1, i, i + 1, xoptions = gtk.FILL, yoptions = gtk.FILL)
  1667.             opt.label.set_alignment(0, 0.5)
  1668.             self.tblJOOther.attach(opt.selector, 1, 2, i, i + 1, xoptions = gtk.FILL, yoptions = 0)
  1669.             opt.selector.set_sensitive(editable)
  1670.             btn = gtk.Button(stock = 'gtk-remove')
  1671.             btn.connect('clicked', self.on_btnJOOtherRemove_clicked)
  1672.             btn.set_data('pyobject', opt)
  1673.             btn.set_sensitive(editable)
  1674.             self.tblJOOther.attach(btn, 2, 3, i, i + 1, xoptions = 0, yoptions = 0)
  1675.             i += 1
  1676.         
  1677.         self.tblJOOther.show_all()
  1678.  
  1679.     
  1680.     def add_job_option(self, name, value = '', supported = '', is_new = True, editable = True):
  1681.         option = options.OptionWidget(name, value, supported, self.option_changed)
  1682.         option.is_new = is_new
  1683.         self.other_job_options.append(option)
  1684.         self.draw_other_job_options(editable = editable)
  1685.         self.server_side_options[name] = option
  1686.         if name in self.changed:
  1687.             option.is_new = False
  1688.         
  1689.         self.changed.add(option)
  1690.         self.setDataButtonState()
  1691.         if is_new:
  1692.             option.selector.grab_focus()
  1693.         
  1694.  
  1695.     
  1696.     def on_btnJOOtherRemove_clicked(self, button):
  1697.         option = button.get_data('pyobject')
  1698.         self.other_job_options.remove(option)
  1699.         self.draw_other_job_options()
  1700.         if option.is_new:
  1701.             self.changed.discard(option)
  1702.         else:
  1703.             self.changed.add(option.name)
  1704.         del self.server_side_options[option.name]
  1705.         self.setDataButtonState()
  1706.  
  1707.     
  1708.     def on_btnNewJobOption_clicked(self, button):
  1709.         name = self.entNewJobOption.get_text()
  1710.         self.add_job_option(name)
  1711.         self.tblJOOther.show_all()
  1712.         self.entNewJobOption.set_text('')
  1713.         self.btnNewJobOption.set_sensitive(False)
  1714.         self.setDataButtonState()
  1715.  
  1716.     
  1717.     def on_entNewJobOption_changed(self, widget):
  1718.         text = self.entNewJobOption.get_text()
  1719.         if len(text) > 0:
  1720.             pass
  1721.         active = text not in self.server_side_options
  1722.         self.btnNewJobOption.set_sensitive(active)
  1723.  
  1724.     
  1725.     def on_entNewJobOption_activate(self, widget):
  1726.         self.on_btnNewJobOption_clicked(widget)
  1727.  
  1728.     
  1729.     def setDataButtonState(self):
  1730.         
  1731.         try:
  1732.             if self.ppd and not bool(self.changed) and self.printer.enabled:
  1733.                 pass
  1734.             possible = not (self.printer.rejecting)
  1735.             for button in [
  1736.                 self.btnPrintTestPage,
  1737.                 self.btnChangePPD,
  1738.                 self.btnSelectDevice]:
  1739.                 button.set_sensitive(possible)
  1740.             
  1741.             commands = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  1742.             if commands:
  1743.                 pass
  1744.             self.btnSelfTest.set_sensitive(possible)
  1745.             if commands:
  1746.                 pass
  1747.             self.btnCleanHeads.set_sensitive(possible)
  1748.         except:
  1749.             pass
  1750.  
  1751.         installablebold = False
  1752.         optionsbold = False
  1753.         if self.conflicts:
  1754.             debugprint('Conflicts detected')
  1755.             self.btnConflict.show()
  1756.             for option in self.conflicts:
  1757.                 if option.tab_label == self.lblPInstallOptions:
  1758.                     installablebold = True
  1759.                     continue
  1760.                 optionsbold = True
  1761.             
  1762.         else:
  1763.             self.btnConflict.hide()
  1764.         installabletext = _('Installable Options')
  1765.         optionstext = _('Printer Options')
  1766.         if installablebold:
  1767.             installabletext = '<b>%s</b>' % installabletext
  1768.         
  1769.         if optionsbold:
  1770.             optionstext = '<b>%s</b>' % optionstext
  1771.         
  1772.         self.lblPInstallOptions.set_markup(installabletext)
  1773.         self.lblPOptions.set_markup(optionstext)
  1774.         store = self.tvPrinterProperties.get_model()
  1775.         if store:
  1776.             for n in range(self.ntbkPrinter.get_n_pages()):
  1777.                 page = self.ntbkPrinter.get_nth_page(n)
  1778.                 label = self.ntbkPrinter.get_tab_label(page)
  1779.                 
  1780.                 try:
  1781.                     if label == self.lblPInstallOptions:
  1782.                         iter = store.get_iter((n,))
  1783.                         store.set_value(iter, 0, installabletext)
  1784.                     elif label == self.lblPOptions:
  1785.                         iter = store.get_iter((n,))
  1786.                         store.set_value(iter, 0, optionstext)
  1787.                 continue
  1788.                 except ValueError:
  1789.                     continue
  1790.                 
  1791.  
  1792.             
  1793.         
  1794.         if len(self.changed) > 0:
  1795.             pass
  1796.         self.btnPrinterPropertiesApply.set_sensitive(not (self.conflicts))
  1797.         if len(self.changed) > 0:
  1798.             pass
  1799.         self.btnPrinterPropertiesOK.set_sensitive(not (self.conflicts))
  1800.  
  1801.     
  1802.     def save_printer(self, printer, saveall = False, parent = None):
  1803.         if parent == None:
  1804.             parent = self.PrinterPropertiesDialog
  1805.         
  1806.         class_deleted = False
  1807.         name = printer.name
  1808.         if printer.is_class:
  1809.             self.cups._begin_operation(_('modifying class %s') % name)
  1810.         else:
  1811.             self.cups._begin_operation(_('modifying printer %s') % name)
  1812.         
  1813.         try:
  1814.             if not (printer.is_class) and self.ppd:
  1815.                 self.getPrinterSettings()
  1816.                 if self.ppd.nondefaultsMarked() or saveall:
  1817.                     self.cups.addPrinter(name, ppd = self.ppd)
  1818.                 
  1819.             
  1820.             if printer.is_class:
  1821.                 new_members = getCurrentClassMembers(self.tvClassMembers)
  1822.                 if not new_members:
  1823.                     dialog = gtk.MessageDialog(flags = 0, type = gtk.MESSAGE_WARNING, buttons = gtk.BUTTONS_YES_NO, message_format = _('This will delete this class!'))
  1824.                     dialog.format_secondary_text(_('Proceed anyway?'))
  1825.                     result = dialog.run()
  1826.                     dialog.destroy()
  1827.                     if result == gtk.RESPONSE_NO:
  1828.                         self.cups._end_operation()
  1829.                         return True
  1830.                     class_deleted = True
  1831.                 
  1832.                 old_members = printer.class_members[:]
  1833.                 for member in new_members:
  1834.                     if member in old_members:
  1835.                         old_members.remove(member)
  1836.                         continue
  1837.                     self.cups.addPrinterToClass(member, name)
  1838.                 
  1839.                 for member in old_members:
  1840.                     self.cups.deletePrinterFromClass(member, name)
  1841.                 
  1842.             
  1843.             location = self.entPLocation.get_text()
  1844.             info = self.entPDescription.get_text()
  1845.             device_uri = self.entPDevice.get_text()
  1846.             enabled = self.chkPEnabled.get_active()
  1847.             accepting = self.chkPAccepting.get_active()
  1848.             shared = self.chkPShared.get_active()
  1849.             if info != printer.info or saveall:
  1850.                 self.cups.setPrinterInfo(name, info)
  1851.             
  1852.             if location != printer.location or saveall:
  1853.                 self.cups.setPrinterLocation(name, location)
  1854.             
  1855.             if not (printer.is_class):
  1856.                 if device_uri != printer.device_uri or saveall:
  1857.                     self.cups.setPrinterDevice(name, device_uri)
  1858.                 
  1859.             if enabled != printer.enabled or saveall:
  1860.                 self.printer.setEnabled(enabled)
  1861.             
  1862.             if accepting == printer.rejecting or saveall:
  1863.                 self.printer.setAccepting(accepting)
  1864.             
  1865.             if shared != printer.is_shared or saveall:
  1866.                 self.printer.setShared(shared)
  1867.             
  1868.             
  1869.             def get_combo_value(cmb):
  1870.                 model = cmb.get_model()
  1871.                 iter = cmb.get_active_iter()
  1872.                 return model.get_value(iter, 1)
  1873.  
  1874.             job_sheet_start = get_combo_value(self.cmbPStartBanner)
  1875.             job_sheet_end = get_combo_value(self.cmbPEndBanner)
  1876.             error_policy = get_combo_value(self.cmbPErrorPolicy)
  1877.             op_policy = get_combo_value(self.cmbPOperationPolicy)
  1878.             if job_sheet_start != printer.job_sheet_start or job_sheet_end != printer.job_sheet_end or saveall:
  1879.                 printer.setJobSheets(job_sheet_start, job_sheet_end)
  1880.             
  1881.             if error_policy != printer.error_policy or saveall:
  1882.                 printer.setErrorPolicy(error_policy)
  1883.             
  1884.             if op_policy != printer.op_policy or saveall:
  1885.                 printer.setOperationPolicy(op_policy)
  1886.             
  1887.             default_allow = self.rbtnPAllow.get_active()
  1888.             except_users = self.getPUsers()
  1889.             if default_allow != printer.default_allow or except_users != printer.except_users or saveall:
  1890.                 printer.setAccess(default_allow, except_users)
  1891.             
  1892.             for option in printer.attributes:
  1893.                 if option not in self.server_side_options:
  1894.                     printer.unsetOption(option)
  1895.                     continue
  1896.             
  1897.             for option in self.server_side_options.itervalues():
  1898.                 if (option.is_changed() or saveall) and option.get_current_value() != option.system_default:
  1899.                     printer.setOption(option.name, option.get_current_value())
  1900.                     continue
  1901.         except cups.IPPError:
  1902.             (e, s) = None
  1903.             show_IPP_Error(e, s, parent)
  1904.             self.cups._end_operation()
  1905.             return True
  1906.  
  1907.         self.cups._end_operation()
  1908.         self.changed = set()
  1909.         if not (self.cups._use_pk) and not self.__dict__.has_key('server_settings'):
  1910.             self.cups._begin_operation(_('fetching server settings'))
  1911.             
  1912.             try:
  1913.                 self.server_settings = self.cups.adminGetServerSettings()
  1914.             except:
  1915.                 nonfatalException()
  1916.  
  1917.             self.cups._end_operation()
  1918.         
  1919.         if class_deleted:
  1920.             self.monitor.update()
  1921.         else:
  1922.             self.cups._begin_operation(_('obtaining queue details'))
  1923.             
  1924.             try:
  1925.                 printers = cupshelpers.getPrinters(self.cups)
  1926.                 this_printer = {
  1927.                     name: printers[name] }
  1928.                 self.printers.update(this_printer)
  1929.             except cups.IPPError:
  1930.                 (e, s) = None
  1931.                 show_IPP_Error(e, s, self.PrinterPropertiesDialog)
  1932.             except KeyError:
  1933.                 self.populateList()
  1934.  
  1935.             self.cups._end_operation()
  1936.         return False
  1937.  
  1938.     
  1939.     def getPrinterSettings(self):
  1940.         for option in self.options.itervalues():
  1941.             option.writeback()
  1942.         
  1943.  
  1944.     
  1945.     def on_tvPrinterProperties_selection_changed(self, selection):
  1946.         (model, iter) = selection.get_selected()
  1947.         if iter:
  1948.             self.printer_properties_last_iter_selected = iter
  1949.         else:
  1950.             
  1951.             try:
  1952.                 iter = self.printer_properties_last_iter_selected
  1953.             except AttributeError:
  1954.                 return None
  1955.  
  1956.             if model.iter_is_valid(iter):
  1957.                 selection.select_iter(iter)
  1958.             
  1959.  
  1960.     
  1961.     def on_tvPrinterProperties_cursor_changed(self, treeview):
  1962.         (path, column) = treeview.get_cursor()
  1963.         if path != None:
  1964.             model = treeview.get_model()
  1965.             iter = model.get_iter(path)
  1966.             n = model.get_value(iter, 1)
  1967.             self.ntbkPrinter.set_current_page(n)
  1968.         
  1969.  
  1970.     
  1971.     def set_system_or_user_default_printer(self, name):
  1972.         userdef = userdefault.UserDefaultPrinter()
  1973.         if name == self.default_printer:
  1974.             userdef.clear()
  1975.             self.populateList()
  1976.             return None
  1977.         userdefault.UserDefaultPrompt(self.set_default_printer, self.populateList, name, _('Set Default Printer'), self.PrintersWindow, _('Do you want to set this as the system-wide default printer?'), _('Set as the _system-wide default printer'), _('_Clear my personal default setting'), _('Set as my _personal default printer'))
  1978.  
  1979.     
  1980.     def set_default_printer(self, name):
  1981.         printer = self.printers[name]
  1982.         reload = False
  1983.         self.cups._begin_operation(_('setting default printer'))
  1984.         
  1985.         try:
  1986.             reload = printer.setAsDefault()
  1987.         except cups.HTTPError:
  1988.             (s,) = None
  1989.             show_HTTP_Error(s, self.PrintersWindow)
  1990.             self.cups._end_operation()
  1991.             return None
  1992.             except cups.IPPError:
  1993.                 (e, msg) = None
  1994.                 show_IPP_Error(e, msg, self.PrintersWindow)
  1995.                 self.cups._end_operation()
  1996.                 return None
  1997.             else:
  1998.                 self.cups._end_operation()
  1999.                 if reload:
  2000.                     self.reconnect()
  2001.                 
  2002.  
  2003.         
  2004.         try:
  2005.             self.populateList()
  2006.         except cups.HTTPError:
  2007.             (s,) = None
  2008.             self.cups = None
  2009.             self.setConnected()
  2010.             self.populateList()
  2011.             show_HTTP_Error(s, self.PrintersWindow)
  2012.  
  2013.  
  2014.     
  2015.     def on_btnPrintTestPage_clicked(self, button):
  2016.         if self.ppd == False:
  2017.             return None
  2018.         custom_testpage = None
  2019.         if self.ppd != False:
  2020.             opt = self.ppd.findOption('PageSize')
  2021.             if opt:
  2022.                 custom_testpage = os.path.join(pkgdata, 'testpage-%s.ps' % opt.defchoice.lower())
  2023.             
  2024.         
  2025.         user = cups.getUser()
  2026.         cups.setUser('')
  2027.         
  2028.         try:
  2029.             c = authconn.Connection(self.PrintersWindow, try_as_root = False, host = self.connect_server, encryption = self.connect_encrypt)
  2030.         except RuntimeError:
  2031.             s = None
  2032.             show_IPP_Error(None, s, self.PrintersWindow)
  2033.             return None
  2034.  
  2035.         job_id = None
  2036.         c._begin_operation(_('printing test page'))
  2037.         
  2038.         try:
  2039.             if custom_testpage and os.path.exists(custom_testpage):
  2040.                 debugprint('Printing custom test page ' + custom_testpage)
  2041.                 job_id = c.printTestPage(self.printer.name, file = custom_testpage)
  2042.             else:
  2043.                 debugprint('Printing default test page')
  2044.                 job_id = c.printTestPage(self.printer.name)
  2045.         except cups.IPPError:
  2046.             (e, msg) = None
  2047.             if e == cups.IPP_NOT_AUTHORIZED and self.connect_server != 'localhost' and self.connect_server[0] != '/':
  2048.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2049.             else:
  2050.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2051.         except:
  2052.             self.connect_server[0] != '/'
  2053.  
  2054.         c._end_operation()
  2055.         cups.setUser(user)
  2056.         if job_id != None:
  2057.             show_info_dialog(_('Submitted'), _('Test page submitted as job %d') % job_id, parent = self.PrintersWindow)
  2058.         
  2059.  
  2060.     
  2061.     def maintenance_command(self, command):
  2062.         (tmpfd, tmpfname) = tempfile.mkstemp()
  2063.         os.write(tmpfd, '#CUPS-COMMAND\n%s\n' % command)
  2064.         os.close(tmpfd)
  2065.         self.cups._begin_operation(_('sending maintenance command'))
  2066.         
  2067.         try:
  2068.             format = 'application/vnd.cups-command'
  2069.             job_id = self.cups.printTestPage(self.printer.name, format = format, file = tmpfname, user = self.connect_user)
  2070.             show_info_dialog(_('Submitted'), _('Maintenance command submitted as job %d') % job_id, parent = self.PrintersWindow)
  2071.         except cups.IPPError:
  2072.             (e, msg) = None
  2073.             if e == cups.IPP_NOT_AUTHORIZED and self.printer.name != 'localhost':
  2074.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2075.             else:
  2076.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2077.         except:
  2078.             self.printer.name != 'localhost'
  2079.  
  2080.         self.cups._end_operation()
  2081.         os.unlink(tmpfname)
  2082.  
  2083.     
  2084.     def on_btnSelfTest_clicked(self, button):
  2085.         self.maintenance_command('PrintSelfTestPage')
  2086.  
  2087.     
  2088.     def on_btnCleanHeads_clicked(self, button):
  2089.         self.maintenance_command('Clean all')
  2090.  
  2091.     
  2092.     def fillComboBox(self, combobox, values, value, translationdict = None):
  2093.         if translationdict == None:
  2094.             translationdict = ppdippstr.TranslactionDict()
  2095.         
  2096.         model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
  2097.         combobox.set_model(model)
  2098.         set_active = False
  2099.         for nr, val in enumerate(values):
  2100.             model.append([
  2101.                 translationdict.get(val),
  2102.                 val])
  2103.             if val == value:
  2104.                 combobox.set_active(nr)
  2105.                 set_active = True
  2106.                 continue
  2107.         
  2108.         if not set_active:
  2109.             combobox.set_active(0)
  2110.         
  2111.  
  2112.     
  2113.     def fillPrinterTab(self, name):
  2114.         self.changed = set()
  2115.         self.options = { }
  2116.         self.conflicts = set()
  2117.         printer = self.printers[name]
  2118.         self.printer = printer
  2119.         printer.getAttributes()
  2120.         
  2121.         try:
  2122.             publishing = printer.other_attributes['server-is-sharing-printers']
  2123.             self.server_is_publishing = publishing
  2124.         except KeyError:
  2125.             pass
  2126.  
  2127.         editable = not (self.printer.discovered)
  2128.         editablePPD = not (self.printer.remote)
  2129.         
  2130.         try:
  2131.             self.ppd = printer.getPPD()
  2132.             self.ppd_local = printer.getPPD()
  2133.             if self.ppd_local != False:
  2134.                 self.ppd_local.localize()
  2135.         except cups.IPPError:
  2136.             (e, m) = None
  2137.             show_IPP_Error(e, m, self.PrintersWindow)
  2138.             self.ppd = False
  2139.         except RuntimeError:
  2140.             show_error_dialog(_('Error'), _('There was a problem connecting to the CUPS server.'), self.PrintersWindow)
  2141.             raise 
  2142.  
  2143.         for widget in (self.entPDescription, self.entPLocation, self.entPDevice):
  2144.             widget.set_editable(editable)
  2145.         
  2146.         for widget in (self.btnSelectDevice, self.btnChangePPD, self.chkPEnabled, self.chkPAccepting, self.chkPShared, self.cmbPStartBanner, self.cmbPEndBanner, self.cmbPErrorPolicy, self.cmbPOperationPolicy, self.rbtnPAllow, self.rbtnPDeny, self.tvPUsers, self.entPUser, self.btnPAddUser, self.btnPDelUser):
  2147.             widget.set_sensitive(editable)
  2148.         
  2149.         self.entPDescription.set_text(printer.info)
  2150.         self.entPLocation.set_text(printer.location)
  2151.         uri = printer.device_uri
  2152.         self.entPDevice.set_text(uri)
  2153.         self.changed.discard(self.entPDevice)
  2154.         for widget in (self.lblPMakeModel2, self.lblPMakeModel, self.btnChangePPD, self.lblPDevice2, self.entPDevice, self.btnSelectDevice):
  2155.             if printer.is_class:
  2156.                 widget.hide()
  2157.                 continue
  2158.             widget.show()
  2159.         
  2160.         
  2161.         try:
  2162.             if printer.is_shared:
  2163.                 if self.server_is_publishing:
  2164.                     self.lblNotPublished.hide_all()
  2165.                 else:
  2166.                     self.lblNotPublished.show_all()
  2167.             else:
  2168.                 self.lblNotPublished.hide_all()
  2169.         except:
  2170.             nonfatalException()
  2171.             self.lblNotPublished.hide_all()
  2172.  
  2173.         self.cmbPStartBanner.set_sensitive(editable)
  2174.         self.cmbPEndBanner.set_sensitive(editable)
  2175.         self.cmbPErrorPolicy.set_sensitive(editable)
  2176.         self.cmbPOperationPolicy.set_sensitive(editable)
  2177.         self.entPUser.set_text('')
  2178.         self.server_side_options = { }
  2179.         for option in self.job_options_widgets.values():
  2180.             if option.name == 'media' and self.ppd:
  2181.                 opt = self.ppd.findOption('PageSize')
  2182.                 if opt:
  2183.                     option.set_default(opt.defchoice)
  2184.                 
  2185.             
  2186.             option_editable = editable
  2187.             
  2188.             try:
  2189.                 value = self.printer.attributes[option.name]
  2190.             except KeyError:
  2191.                 option.reinit(None)
  2192.  
  2193.             
  2194.             try:
  2195.                 if self.printer.possible_attributes.has_key(option.name):
  2196.                     supported = self.printer.possible_attributes[option.name][1]
  2197.                     option.reinit(value, supported = supported)
  2198.                 else:
  2199.                     option.reinit(value)
  2200.                 self.server_side_options[option.name] = option
  2201.             except:
  2202.                 option_editable = False
  2203.                 show_error_dialog(_('Error'), _("Option '%s' has value '%s' and cannot be edited.") % (option.name, value), self.PrintersWindow)
  2204.  
  2205.             option.widget.set_sensitive(option_editable)
  2206.             if not editable:
  2207.                 option.button.set_sensitive(False)
  2208.                 continue
  2209.         
  2210.         self.other_job_options = []
  2211.         self.draw_other_job_options(editable = editable)
  2212.         for option in self.printer.attributes.keys():
  2213.             if self.server_side_options.has_key(option):
  2214.                 continue
  2215.             
  2216.             value = self.printer.attributes[option]
  2217.             if self.printer.possible_attributes.has_key(option):
  2218.                 supported = self.printer.possible_attributes[option][1]
  2219.             elif isinstance(value, bool):
  2220.                 supported = [
  2221.                     'true',
  2222.                     'false']
  2223.                 value = str(value).lower()
  2224.             else:
  2225.                 supported = ''
  2226.                 value = str(value)
  2227.             self.add_job_option(option, value = value, supported = supported, is_new = False, editable = editable)
  2228.         
  2229.         self.entNewJobOption.set_text('')
  2230.         self.entNewJobOption.set_sensitive(editable)
  2231.         self.btnNewJobOption.set_sensitive(False)
  2232.         if printer.is_class:
  2233.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2234.             if tab_nr != -1:
  2235.                 self.ntbkPrinter.remove_page(tab_nr)
  2236.             
  2237.             self.fillClassMembers(name, editable)
  2238.         else:
  2239.             self.fillPrinterOptions(name, editablePPD)
  2240.         self.updateMarkerLevels()
  2241.         self.updateStateReasons()
  2242.         self.updatePrinterPropertiesTreeView()
  2243.         self.changed = set()
  2244.         self.updatePrinterProperties()
  2245.         self.setDataButtonState()
  2246.  
  2247.     
  2248.     def updatePrinterPropertiesTreeView(self):
  2249.         store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
  2250.         self.ntbkPrinter.set_show_tabs(False)
  2251.         for n in range(self.ntbkPrinter.get_n_pages()):
  2252.             page = self.ntbkPrinter.get_nth_page(n)
  2253.             label = self.ntbkPrinter.get_tab_label(page)
  2254.             iter = store.append(None)
  2255.             store.set_value(iter, 0, label.get_text())
  2256.             store.set_value(iter, 1, n)
  2257.         
  2258.         sel = self.tvPrinterProperties.get_selection()
  2259.         self.tvPrinterProperties.set_model(store)
  2260.  
  2261.     
  2262.     def updateMarkerLevels(self):
  2263.         printer = self.printer
  2264.         for widget in self.vboxMarkerLevels.get_children():
  2265.             self.vboxMarkerLevels.remove(widget)
  2266.         
  2267.         marker_info = dict()
  2268.         for attr in [
  2269.             'marker-colors',
  2270.             'marker-names',
  2271.             'marker-types',
  2272.             'marker-levels']:
  2273.             val = printer.other_attributes.get(attr, [])
  2274.             if type(val) != list:
  2275.                 val = [
  2276.                     val]
  2277.             
  2278.             marker_info[attr] = val
  2279.         
  2280.         markers = map((lambda color, name, type, level: (color, name, type, level)), marker_info['marker-colors'], marker_info['marker-names'], marker_info['marker-types'], marker_info['marker-levels'])
  2281.         debugprint(markers)
  2282.         can_refresh = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  2283.         self.btnRefreshMarkerLevels.set_sensitive(can_refresh)
  2284.         if len(markers) == 0:
  2285.             label = gtk.Label(_('Marker levels are not reported for this printer.'))
  2286.             label.set_line_wrap(True)
  2287.             label.set_alignment(0, 0)
  2288.             self.vboxMarkerLevels.pack_start(label, False, False, 0)
  2289.         else:
  2290.             num_markers = 0
  2291.             cols = len(markers)
  2292.             rows = 1 + (cols - 1) / 4
  2293.             if cols > 4:
  2294.                 cols = 4
  2295.             
  2296.             table = gtk.Table(rows = rows, columns = cols, homogeneous = True)
  2297.             table.set_col_spacings(6)
  2298.             table.set_row_spacings(12)
  2299.             self.vboxMarkerLevels.pack_start(table)
  2300.             for color, name, marker_type, level in markers:
  2301.                 if name == None:
  2302.                     name = ''
  2303.                 else:
  2304.                     ppd = printer.getPPD()
  2305.                     if ppd != False:
  2306.                         localized_name = ppd.localizeMarkerName(name)
  2307.                         if localized_name != None:
  2308.                             name = localized_name
  2309.                         
  2310.                     
  2311.                 row = num_markers / 4
  2312.                 col = num_markers % 4
  2313.                 vbox = gtk.VBox(spacing = 6)
  2314.                 subhbox = gtk.HBox()
  2315.                 inklevel = gtkinklevel.GtkInkLevel(color, level)
  2316.                 subhbox.pack_start(inklevel, True, False, 0)
  2317.                 vbox.pack_start(subhbox, False, False, 0)
  2318.                 label = gtk.Label(name)
  2319.                 label.set_line_wrap(True)
  2320.                 vbox.pack_start(label, False, False, 0)
  2321.                 table.attach(vbox, col, col + 1, row, row + 1)
  2322.                 num_markers += 1
  2323.             
  2324.         self.vboxMarkerLevels.show_all()
  2325.  
  2326.     
  2327.     def on_btnRefreshMarkerLevels_clicked(self, button):
  2328.         self.maintenance_command('ReportLevels')
  2329.  
  2330.     
  2331.     def updateStateReasons(self):
  2332.         printer = self.printer
  2333.         reasons = printer.other_attributes.get('printer-state-reasons', [])
  2334.         store = gtk.ListStore(str, str)
  2335.         any = False
  2336.         for reason in reasons:
  2337.             if reason == 'none':
  2338.                 break
  2339.             
  2340.             any = True
  2341.             iter = store.append(None)
  2342.             r = statereason.StateReason(printer.name, reason)
  2343.             if r.get_reason() == 'paused':
  2344.                 icon = gtk.STOCK_MEDIA_PAUSE
  2345.             else:
  2346.                 icon = statereason.StateReason.LEVEL_ICON[r.get_level()]
  2347.             store.set_value(iter, 0, icon)
  2348.             (title, text) = r.get_description()
  2349.             store.set_value(iter, 1, text)
  2350.         
  2351.         self.tvPrinterStateReasons.set_model(store)
  2352.         page = 0
  2353.         if any:
  2354.             page = 1
  2355.         
  2356.         self.ntbkPrinterStateReasons.set_current_page(page)
  2357.  
  2358.     
  2359.     def set_printer_state_reason_icon(self, column, cell, model, iter, *data):
  2360.         icon = model.get_value(iter, 0)
  2361.         theme = gtk.icon_theme_get_default()
  2362.         
  2363.         try:
  2364.             pixbuf = theme.load_icon(icon, 22, 0)
  2365.             cell.set_property('pixbuf', pixbuf)
  2366.         except gobject.GError:
  2367.             exc = None
  2368.  
  2369.  
  2370.     
  2371.     def set_printer_state_reason_text(self, column, cell, model, iter, *data):
  2372.         cell.set_property('text', model.get_value(iter, 1))
  2373.  
  2374.     
  2375.     def updatePrinterProperties(self):
  2376.         debugprint('update printer properties')
  2377.         printer = self.printer
  2378.         self.lblPMakeModel.set_text(printer.make_and_model)
  2379.         state = self.printer_states.get(printer.state, _('Unknown'))
  2380.         reason = printer.other_attributes.get('printer-state-message', '')
  2381.         if len(reason) > 0:
  2382.             state += ' - ' + reason
  2383.         
  2384.         self.lblPState.set_text(state)
  2385.         if len(self.changed) == 0:
  2386.             debugprint('no changes yet: full printer properties update')
  2387.             self.chkPEnabled.set_active(printer.enabled)
  2388.             self.chkPAccepting.set_active(not (printer.rejecting))
  2389.             self.chkPShared.set_active(printer.is_shared)
  2390.             self.fillComboBox(self.cmbPStartBanner, printer.job_sheets_supported, printer.job_sheet_start, ppdippstr.job_sheets)
  2391.             self.fillComboBox(self.cmbPEndBanner, printer.job_sheets_supported, printer.job_sheet_end, ppdippstr.job_sheets)
  2392.             self.fillComboBox(self.cmbPErrorPolicy, printer.error_policy_supported, printer.error_policy, ppdippstr.printer_error_policy)
  2393.             self.fillComboBox(self.cmbPOperationPolicy, printer.op_policy_supported, printer.op_policy, ppdippstr.printer_op_policy)
  2394.             self.rbtnPAllow.set_active(printer.default_allow)
  2395.             self.rbtnPDeny.set_active(not (printer.default_allow))
  2396.             self.setPUsers(printer.except_users)
  2397.             self.updateMarkerLevels()
  2398.             self.updateStateReasons()
  2399.             self.updatePrinterPropertiesTreeView()
  2400.         
  2401.  
  2402.     
  2403.     def fillPrinterOptions(self, name, editable):
  2404.         tab_nr = self.ntbkPrinter.page_num(self.algnClassMembers)
  2405.         if tab_nr != -1:
  2406.             self.ntbkPrinter.remove_page(tab_nr)
  2407.         
  2408.         for widget in self.vbPInstallOptions.get_children():
  2409.             self.vbPInstallOptions.remove(widget)
  2410.         
  2411.         for widget in self.vbPOptions.get_children():
  2412.             self.vbPOptions.remove(widget)
  2413.         
  2414.         if self.ntbkPrinter.page_num(self.swPOptions) == -1:
  2415.             self.ntbkPrinter.insert_page(self.swPOptions, self.lblPOptions, self.static_tabs)
  2416.         
  2417.         if not self.ppd:
  2418.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2419.             if tab_nr != -1:
  2420.                 self.ntbkPrinter.remove_page(tab_nr)
  2421.             
  2422.             tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2423.             if tab_nr != -1:
  2424.                 self.ntbkPrinter.remove_page(tab_nr)
  2425.             
  2426.             return None
  2427.         ppd = self.ppd
  2428.         ppd.markDefaults()
  2429.         self.ppd_local.markDefaults()
  2430.         hasInstallableOptions = False
  2431.         for group in self.ppd_local.optionGroups:
  2432.             table = gtk.Table(1, 3, False)
  2433.             table.set_col_spacings(6)
  2434.             table.set_row_spacings(6)
  2435.             container.add(table)
  2436.             rows = 0
  2437.             self.option_inputslot = None
  2438.             self.option_manualfeed = None
  2439.             for nr, option in enumerate(group.options):
  2440.                 if option.keyword == 'PageRegion':
  2441.                     continue
  2442.                 
  2443.                 rows += 1
  2444.                 table.resize(rows, 3)
  2445.                 o = OptionWidget(option, ppd, self, tab_label = tab_label)
  2446.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  2447.                 hbox = gtk.HBox()
  2448.                 if o.label:
  2449.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  2450.                     a.set_padding(0, 0, 0, 6)
  2451.                     a.add(o.label)
  2452.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2453.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2454.                 else:
  2455.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2456.                 hbox.pack_start(o.selector, False)
  2457.                 self.options[option.keyword] = o
  2458.                 o.selector.set_sensitive(editable)
  2459.                 if option.keyword == 'InputSlot':
  2460.                     self.option_inputslot = o
  2461.                     continue
  2462.                 if option.keyword == 'ManualFeed':
  2463.                     self.option_manualfeed = o
  2464.                     continue
  2465.             
  2466.         
  2467.         if not hasInstallableOptions:
  2468.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2469.             if tab_nr != -1:
  2470.                 self.ntbkPrinter.remove_page(tab_nr)
  2471.             
  2472.         
  2473.         for option in self.options.itervalues():
  2474.             conflicts = option.checkConflicts()
  2475.             if conflicts:
  2476.                 self.conflicts.add(option)
  2477.                 continue
  2478.         
  2479.         self.swPInstallOptions.show_all()
  2480.         self.swPOptions.show_all()
  2481.  
  2482.     
  2483.     def fillClassMembers(self, name, editable):
  2484.         printer = self.printers[name]
  2485.         self.btnClassAddMember.set_sensitive(editable)
  2486.         self.btnClassDelMember.set_sensitive(editable)
  2487.         tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2488.         if tab_nr != -1:
  2489.             self.ntbkPrinter.remove_page(tab_nr)
  2490.         
  2491.         if self.ntbkPrinter.page_num(self.algnClassMembers) == -1:
  2492.             self.ntbkPrinter.insert_page(self.algnClassMembers, self.lblClassMembers, self.static_tabs)
  2493.         
  2494.         model_members = self.tvClassMembers.get_model()
  2495.         model_not_members = self.tvClassNotMembers.get_model()
  2496.         model_members.clear()
  2497.         model_not_members.clear()
  2498.         names = self.printers.keys()
  2499.         names.sort()
  2500.         for name in names:
  2501.             p = self.printers[name]
  2502.             if p is not printer:
  2503.                 if name in printer.class_members:
  2504.                     model_members.append((name,))
  2505.                 else:
  2506.                     model_not_members.append((name,))
  2507.             name in printer.class_members
  2508.         
  2509.  
  2510.     
  2511.     def on_btnClassAddMember_clicked(self, button):
  2512.         moveClassMembers(self.tvClassNotMembers, self.tvClassMembers)
  2513.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2514.             self.changed.add(self.tvClassMembers)
  2515.         else:
  2516.             self.changed.discard(self.tvClassMembers)
  2517.         self.setDataButtonState()
  2518.  
  2519.     
  2520.     def on_btnClassDelMember_clicked(self, button):
  2521.         moveClassMembers(self.tvClassMembers, self.tvClassNotMembers)
  2522.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2523.             self.changed.add(self.tvClassMembers)
  2524.         else:
  2525.             self.changed.discard(self.tvClassMembers)
  2526.         self.setDataButtonState()
  2527.  
  2528.     
  2529.     def on_quit_activate(self, widget, event = None):
  2530.         self.monitor.cleanup()
  2531.         while len(self.jobviewers) > 0:
  2532.             self.jobviewers[0].cleanup()
  2533.         del self.mainlist
  2534.         del self.printers
  2535.         gtk.main_quit()
  2536.  
  2537.     
  2538.     def is_rename_possible(self, name):
  2539.         jobs = self.printers[name].jobsQueued(limit = 1)
  2540.         if len(jobs) > 0:
  2541.             show_error_dialog(_('Cannot Rename'), _('There are queued jobs.'), parent = self.PrintersWindow)
  2542.             return False
  2543.         return True
  2544.  
  2545.     
  2546.     def rename_confirmed_by_user(self, name):
  2547.         '''
  2548.         Renaming deletes job history. So if we have some completed jobs,
  2549.         inform the user and let him confirm the renaming.
  2550.         '''
  2551.         preserved_jobs = self.printers[name].jobsPreserved(limit = 1)
  2552.         if len(preserved_jobs) > 0:
  2553.             dialog = gtk.MessageDialog(self.PrintersWindow, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK_CANCEL, _('Renaming will lose history'))
  2554.             dialog.format_secondary_text(_('Completed jobs will no longer be available for re-printing.'))
  2555.             result = dialog.run()
  2556.             dialog.destroy()
  2557.             if result == gtk.RESPONSE_CANCEL:
  2558.                 return False
  2559.         
  2560.         return True
  2561.  
  2562.     
  2563.     def on_rename_activate(self, UNUSED):
  2564.         tuple = self.dests_iconview.get_cursor()
  2565.         if tuple == None:
  2566.             return None
  2567.         (path, cell) = tuple
  2568.         if type(cell) != gtk.CellRendererText:
  2569.             cells = self.dests_iconview.get_cells()
  2570.             for cell in cells:
  2571.                 if type(cell) == gtk.CellRendererText:
  2572.                     break
  2573.                     continue
  2574.                 tuple == None
  2575.             
  2576.             if type(cell) != gtk.CellRendererText:
  2577.                 return None
  2578.         
  2579.         model = self.dests_iconview.get_model()
  2580.         iter = model.get_iter(path)
  2581.         name = unicode(model.get_value(iter, 2))
  2582.         if not self.is_rename_possible(name):
  2583.             return None
  2584.         if not self.rename_confirmed_by_user(name):
  2585.             return None
  2586.         cell.set_property('editable', True)
  2587.         self.dests_iconview.set_cursor(path, cell, start_editing = True)
  2588.         ids = []
  2589.         ids.append(cell.connect('edited', self.printer_name_edited))
  2590.         ids.append(cell.connect('editing-canceled', self.printer_name_edit_cancel))
  2591.         self.rename_sigids = ids
  2592.  
  2593.     
  2594.     def printer_name_edited(self, cell, path, newname):
  2595.         model = self.dests_iconview.get_model()
  2596.         iter = model.get_iter(path)
  2597.         name = unicode(model.get_value(iter, 2))
  2598.         debugprint('edited: %s -> %s' % (name, newname))
  2599.         
  2600.         try:
  2601.             self.rename_printer(name, newname)
  2602.         finally:
  2603.             cell.stop_editing(canceled = False)
  2604.             cell.set_property('editable', False)
  2605.             for id in self.rename_sigids:
  2606.                 cell.disconnect(id)
  2607.             
  2608.  
  2609.  
  2610.     
  2611.     def printer_name_edit_cancel(self, cell):
  2612.         debugprint('editing-canceled')
  2613.         cell.stop_editing(canceled = True)
  2614.         cell.set_property('editable', False)
  2615.         for id in self.rename_sigids:
  2616.             cell.disconnect(id)
  2617.         
  2618.  
  2619.     
  2620.     def rename_printer(self, old_name, new_name):
  2621.         if old_name == new_name:
  2622.             return None
  2623.         
  2624.         try:
  2625.             self.fillPrinterTab(old_name)
  2626.         except RuntimeError:
  2627.             old_name == new_name
  2628.             old_name == new_name
  2629.         except:
  2630.             old_name == new_name
  2631.  
  2632.         if not self.is_rename_possible(old_name):
  2633.             return None
  2634.         self.cups._begin_operation(_('renaming printer'))
  2635.         rejecting = self.printer.rejecting
  2636.         if not rejecting:
  2637.             
  2638.             try:
  2639.                 self.printer.setAccepting(False)
  2640.                 if not self.is_rename_possible(old_name):
  2641.                     self.printer.setAccepting(True)
  2642.                     self.cups._end_operation()
  2643.                     return None
  2644.             except cups.IPPError:
  2645.                 self.is_rename_possible(old_name)
  2646.                 (e, msg) = self.is_rename_possible(old_name)
  2647.                 old_name == new_name
  2648.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2649.                 self.cups._end_operation()
  2650.                 return None
  2651.             
  2652.  
  2653.         self.is_rename_possible(old_name)<EXCEPTION MATCH>cups.IPPError
  2654.         self.copy_printer(new_name) if self.copy_printer(new_name) else self.copy_printer(new_name)
  2655.         if self.default_printer == old_name:
  2656.             reload = False
  2657.             
  2658.             try:
  2659.                 reload = self.printer.setAsDefault()
  2660.             except cups.HTTPError:
  2661.                 self.is_rename_possible(old_name)
  2662.                 (s,) = self.is_rename_possible(old_name)
  2663.                 self.is_rename_possible(old_name)
  2664.                 show_HTTP_Error(s, self.PrintersWindow)
  2665.             except cups.IPPError:
  2666.                 (e, msg) = None
  2667.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2668.             except:
  2669.                 old_name == new_name
  2670.  
  2671.             if reload:
  2672.                 self.reconnect()
  2673.             
  2674.         
  2675.         
  2676.         try:
  2677.             self.cups.deletePrinter(old_name)
  2678.         except cups.HTTPError:
  2679.             (s,) = None
  2680.             show_HTTP_Error(s, self.PrintersWindow)
  2681.         except cups.IPPError:
  2682.             (e, msg) = None
  2683.             show_IPP_Error(e, msg, self.PrintersWindow)
  2684.  
  2685.         self.cups._end_operation()
  2686.         
  2687.         def select_new_printer(model, path, iter):
  2688.             name = unicode(model.get_value(iter, 2))
  2689.             print name, new_name
  2690.             if name == new_name:
  2691.                 self.dests_iconview.select_path(path)
  2692.             
  2693.  
  2694.         self.populateList()
  2695.         model = self.dests_iconview.get_model()
  2696.         model.foreach(select_new_printer)
  2697.  
  2698.     
  2699.     def copy_printer(self, new_name):
  2700.         self.printer.name = new_name
  2701.         self.printer.class_members = []
  2702.         self.cups._begin_operation(_('copying printer'))
  2703.         ret = self.save_printer(self.printer, saveall = True, parent = self.PrintersWindow)
  2704.         self.cups._end_operation()
  2705.         return ret
  2706.  
  2707.     
  2708.     def on_copy_activate(self, UNUSED):
  2709.         iconview = self.dests_iconview
  2710.         paths = iconview.get_selected_items()
  2711.         model = self.dests_iconview.get_model()
  2712.         iter = model.get_iter(paths[0])
  2713.         name = unicode(model.get_value(iter, 2))
  2714.         self.entCopyName.set_text(name)
  2715.         self.NewPrinterName.set_transient_for(self.PrintersWindow)
  2716.         result = self.NewPrinterName.run()
  2717.         self.NewPrinterName.hide()
  2718.         if result == gtk.RESPONSE_CANCEL:
  2719.             return None
  2720.         
  2721.         try:
  2722.             self.fillPrinterTab(name)
  2723.         except RuntimeError:
  2724.             result == gtk.RESPONSE_CANCEL
  2725.             result == gtk.RESPONSE_CANCEL
  2726.         except:
  2727.             result == gtk.RESPONSE_CANCEL
  2728.  
  2729.         self.copy_printer(self.entCopyName.get_text())
  2730.         self.monitor.update()
  2731.  
  2732.     
  2733.     def on_entCopyName_changed(self, widget):
  2734.         text = unicode(widget.get_text())
  2735.         new_text = text
  2736.         new_text = new_text.replace('/', '')
  2737.         new_text = new_text.replace('#', '')
  2738.         new_text = new_text.replace(' ', '')
  2739.         if text != new_text:
  2740.             widget.set_text(new_text)
  2741.         
  2742.         self.btnCopyOk.set_sensitive(self.checkNPName(new_text))
  2743.  
  2744.     
  2745.     def on_delete_activate(self, UNUSED):
  2746.         if isinstance(self.current_groups_pane_item, StaticGroupItem):
  2747.             paths = self.dests_iconview.get_selected_items()
  2748.             model = self.dests_iconview.get_model()
  2749.             selected_names = []
  2750.             for path in paths:
  2751.                 selected_names.append(model[path][2])
  2752.             
  2753.             self.current_groups_pane_item.remove_queues(selected_names)
  2754.             self.populateList()
  2755.         else:
  2756.             self.delete_selected_printer_queues()
  2757.  
  2758.     
  2759.     def delete_selected_printer_queues(self):
  2760.         paths = self.dests_iconview.get_selected_items()
  2761.         model = self.dests_iconview.get_model()
  2762.         n = len(paths)
  2763.         if n == 1:
  2764.             iter = model.get_iter(paths[0])
  2765.             object = model.get_value(iter, 0)
  2766.             name = model.get_value(iter, 2)
  2767.             if object.is_class:
  2768.                 message_format = _("Really delete class '%s'?") % name
  2769.             else:
  2770.                 message_format = _("Really delete printer '%s'?") % name
  2771.         else:
  2772.             message_format = _('Really delete selected destinations?')
  2773.         dialog = gtk.MessageDialog(self.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, message_format)
  2774.         dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_DELETE, gtk.RESPONSE_ACCEPT)
  2775.         dialog.set_default_response(gtk.RESPONSE_REJECT)
  2776.         result = dialog.run()
  2777.         dialog.destroy()
  2778.         if result != gtk.RESPONSE_ACCEPT:
  2779.             return None
  2780.         
  2781.         try:
  2782.             for path in paths:
  2783.                 iter = model.get_iter(path)
  2784.                 name = model.get_value(iter, 2)
  2785.                 self.cups._begin_operation(_('deleting printer %s') % name)
  2786.                 name = unicode(name)
  2787.                 self.cups.deletePrinter(name)
  2788.                 self.cups._end_operation()
  2789.         except cups.IPPError:
  2790.             result != gtk.RESPONSE_ACCEPT
  2791.             (e, msg) = result != gtk.RESPONSE_ACCEPT
  2792.             self.cups._end_operation()
  2793.             show_IPP_Error(e, msg, self.PrintersWindow)
  2794.         except:
  2795.             result != gtk.RESPONSE_ACCEPT
  2796.  
  2797.         self.changed = set()
  2798.         self.monitor.update()
  2799.  
  2800.     
  2801.     def on_enabled_activate(self, toggle_action):
  2802.         if self.updating_widgets:
  2803.             return None
  2804.         enable = toggle_action.get_active()
  2805.         iconview = self.dests_iconview
  2806.         paths = iconview.get_selected_items()
  2807.         model = iconview.get_model()
  2808.         for path in paths:
  2809.             iter = model.get_iter(path)
  2810.             printer = model.get_value(iter, 0)
  2811.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2812.             self.cups._begin_operation(_('modifying printer %s') % name)
  2813.             
  2814.             try:
  2815.                 printer.setEnabled(enable)
  2816.             except cups.IPPError:
  2817.                 self.updating_widgets
  2818.                 (e, m) = self.updating_widgets
  2819.                 errordialogs.show_IPP_Error(e, m, self.PrintersWindow)
  2820.                 self.cups._end_operation()
  2821.                 break
  2822.             except:
  2823.                 self.updating_widgets
  2824.  
  2825.             self.cups._end_operation()
  2826.         
  2827.         self.monitor.update()
  2828.  
  2829.     
  2830.     def on_shared_activate(self, menuitem):
  2831.         if self.updating_widgets:
  2832.             return None
  2833.         share = menuitem.get_active()
  2834.         iconview = self.dests_iconview
  2835.         paths = iconview.get_selected_items()
  2836.         model = iconview.get_model()
  2837.         success = False
  2838.         for path in paths:
  2839.             iter = model.get_iter(path)
  2840.             printer = model.get_value(iter, 0)
  2841.             self.cups._begin_operation(_('modifying printer %s') % printer.name)
  2842.             
  2843.             try:
  2844.                 printer.setShared(share)
  2845.                 success = True
  2846.             except cups.IPPError:
  2847.                 self.updating_widgets
  2848.                 (e, m) = self.updating_widgets
  2849.                 show_IPP_Error(e, m, self.PrintersWindow)
  2850.                 self.cups._end_operation()
  2851.                 break
  2852.             except:
  2853.                 self.updating_widgets
  2854.  
  2855.             self.cups._end_operation()
  2856.         
  2857.         if success and share:
  2858.             self.advise_publish()
  2859.         
  2860.         
  2861.         def deferred_refresh():
  2862.             self.populateList()
  2863.             return False
  2864.  
  2865.         gobject.idle_add(deferred_refresh)
  2866.  
  2867.     
  2868.     def advise_publish(self):
  2869.         if not self.server_is_publishing:
  2870.             show_info_dialog(_('Publish Shared Printers'), _("Shared printers are not available to other people unless the 'Publish shared printers' option is enabled in the server settings."), parent = self.PrintersWindow)
  2871.         
  2872.  
  2873.     
  2874.     def on_set_as_default_activate(self, UNUSED):
  2875.         iconview = self.dests_iconview
  2876.         paths = iconview.get_selected_items()
  2877.         model = iconview.get_model()
  2878.         iter = model.get_iter(paths[0])
  2879.         name = unicode(model.get_value(iter, 2))
  2880.         self.set_system_or_user_default_printer(name)
  2881.  
  2882.     
  2883.     def on_edit_activate(self, UNUSED):
  2884.         paths = self.dests_iconview.get_selected_items()
  2885.         self.dests_iconview_item_activated(self.dests_iconview, paths[0])
  2886.  
  2887.     
  2888.     def on_create_class_activate(self, UNUSED):
  2889.         paths = self.dests_iconview.get_selected_items()
  2890.         class_members = []
  2891.         model = self.dests_iconview.get_model()
  2892.         for path in paths:
  2893.             iter = model.get_iter(path)
  2894.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2895.             class_members.append(name)
  2896.         
  2897.         self.newPrinterGUI.init('class')
  2898.         out_model = self.newPrinterGUI.tvNCNotMembers.get_model()
  2899.         in_model = self.newPrinterGUI.tvNCMembers.get_model()
  2900.         iter = out_model.get_iter_first()
  2901.         while iter != None:
  2902.             next = out_model.iter_next(iter)
  2903.             data = out_model.get(iter, 0)
  2904.             if data[0] in class_members:
  2905.                 in_model.append(data)
  2906.                 out_model.remove(iter)
  2907.             
  2908.             iter = next
  2909.  
  2910.     
  2911.     def on_view_print_queue_activate(self, UNUSED):
  2912.         paths = self.dests_iconview.get_selected_items()
  2913.         if len(paths):
  2914.             specific_dests = []
  2915.             model = self.dests_iconview.get_model()
  2916.             for path in paths:
  2917.                 iter = model.get_iter(path)
  2918.                 name = unicode(model.get_value(iter, 2), 'utf-8')
  2919.                 specific_dests.append(name)
  2920.             
  2921.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, specific_dests = specific_dests, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2922.         else:
  2923.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2924.         self.jobviewers.append(viewer)
  2925.  
  2926.     
  2927.     def on_jobviewer_exit(self, viewer):
  2928.         i = self.jobviewers.index(viewer)
  2929.         del self.jobviewers[i]
  2930.  
  2931.     
  2932.     def on_view_groups_activate(self, widget):
  2933.         if widget.get_active():
  2934.             if not self.groups_pane_visible:
  2935.                 self.view_area_vbox.remove(self.view_area_scrolledwindow)
  2936.                 self.view_area_hpaned.add2(self.view_area_scrolledwindow)
  2937.                 self.view_area_vbox.add(self.view_area_hpaned)
  2938.                 self.view_area_vbox.show_all()
  2939.                 self.groups_pane_visible = True
  2940.             
  2941.         elif self.groups_pane_visible:
  2942.             self.view_area_vbox.remove(self.view_area_hpaned)
  2943.             self.view_area_hpaned.remove(self.view_area_scrolledwindow)
  2944.             self.view_area_vbox.add(self.view_area_scrolledwindow)
  2945.             self.view_area_vbox.show_all()
  2946.             self.groups_pane_visible = False
  2947.         
  2948.  
  2949.     
  2950.     def on_view_discovered_printers_activate(self, UNUSED):
  2951.         self.populateList()
  2952.  
  2953.     
  2954.     def on_troubleshoot_activate(self, widget):
  2955.         if not self.__dict__.has_key('troubleshooter'):
  2956.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit)
  2957.         
  2958.  
  2959.     
  2960.     def on_troubleshoot_quit(self, troubleshooter):
  2961.         del self.troubleshooter
  2962.  
  2963.     
  2964.     def on_save_as_group_activate(self, UNUSED):
  2965.         model = self.dests_iconview.get_model()
  2966.         printer_queues = []
  2967.         for object in model:
  2968.             printer_queues.append(object[2])
  2969.         
  2970.         self.groups_pane.create_new_group(printer_queues, self.current_filter_text)
  2971.  
  2972.     
  2973.     def on_save_as_search_group_activate(self, UNUSED):
  2974.         criterion = None
  2975.         if self.current_filter_mode == 'filter-name':
  2976.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_NAME, value = self.current_filter_text)
  2977.         elif self.current_filter_mode == 'filter-description':
  2978.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_DESC, value = self.current_filter_text)
  2979.         elif self.current_filter_mode == 'filter-location':
  2980.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_LOCATION, value = self.current_filter_text)
  2981.         elif self.current_filter_mode == 'filter-manufacturer':
  2982.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_MANUF, value = self.current_filter_text)
  2983.         else:
  2984.             nonfatalException()
  2985.             return None
  2986.         (self.current_filter_mode == 'filter-name').groups_pane.create_new_search_group(criterion, self.current_filter_text)
  2987.  
  2988.     
  2989.     def on_about_activate(self, widget):
  2990.         self.AboutDialog.set_transient_for(self.PrintersWindow)
  2991.         self.AboutDialog.run()
  2992.         self.AboutDialog.hide()
  2993.  
  2994.     
  2995.     def fillServerTab(self):
  2996.         self.changed = set()
  2997.         self.cups._begin_operation(_('fetching server settings'))
  2998.         
  2999.         try:
  3000.             self.server_settings = self.cups.adminGetServerSettings()
  3001.         except cups.IPPError:
  3002.             (e, m) = None
  3003.             show_IPP_Error(e, m, self.PrintersWindow)
  3004.             self.cups._end_operation()
  3005.             raise 
  3006.  
  3007.         self.cups._end_operation()
  3008.         for widget, setting in [
  3009.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  3010.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  3011.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  3012.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  3013.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  3014.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  3015.             widget.set_data('setting', setting)
  3016.             if self.server_settings.has_key(setting):
  3017.                 widget.set_active(int(self.server_settings[setting]))
  3018.                 widget.set_sensitive(True)
  3019.                 continue
  3020.             widget.set_active(False)
  3021.             widget.set_sensitive(False)
  3022.         
  3023.         self.setDataButtonState()
  3024.         
  3025.         try:
  3026.             flag = cups.CUPS_SERVER_SHARE_PRINTERS
  3027.             publishing = int(self.server_settings[flag])
  3028.             self.server_is_publishing = publishing
  3029.         except AttributeError:
  3030.             pass
  3031.  
  3032.         self.on_server_changed(self.chkServerShare)
  3033.  
  3034.     
  3035.     def on_server_changed(self, widget):
  3036.         setting = widget.get_data('setting')
  3037.         if self.server_settings.has_key(setting):
  3038.             if str(int(widget.get_active())) == self.server_settings[setting]:
  3039.                 self.changed.discard(widget)
  3040.             else:
  3041.                 self.changed.add(widget)
  3042.         
  3043.         sharing = self.chkServerShare.get_active()
  3044.         if sharing:
  3045.             pass
  3046.         self.chkServerShareAny.set_sensitive(self.server_settings.has_key(try_CUPS_SERVER_REMOTE_ANY))
  3047.         self.setDataButtonState()
  3048.  
  3049.     
  3050.     def save_serversettings(self):
  3051.         setting_dict = self.server_settings.copy()
  3052.         for widget, setting in [
  3053.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  3054.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  3055.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  3056.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  3057.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  3058.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  3059.             if not self.server_settings.has_key(setting):
  3060.                 continue
  3061.             
  3062.             setting_dict[setting] = str(int(widget.get_active()))
  3063.         
  3064.         self.cups._begin_operation(_('modifying server settings'))
  3065.         
  3066.         try:
  3067.             self.cups.adminSetServerSettings(setting_dict)
  3068.         except cups.IPPError:
  3069.             (e, m) = None
  3070.             show_IPP_Error(e, m, self.ServerSettingsDialog)
  3071.             self.cups._end_operation()
  3072.             return True
  3073.             except RuntimeError:
  3074.                 s = None
  3075.                 show_IPP_Error(None, s, self.ServerSettingsDialog)
  3076.                 self.cups._end_operation()
  3077.                 return True
  3078.             else:
  3079.                 self.cups._end_operation()
  3080.                 self.changed = set()
  3081.                 self.setDataButtonState()
  3082.                 old_setting = self.server_settings.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3083.                 new_setting = setting_dict.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3084.                 if 0 and old_setting == '0' and new_setting != '0':
  3085.                     show_info_dialog(_('Review Firewall'), _('You may need to adjust the firewall to allow network printing to this computer.') + '\n\n' + TEXT_start_firewall_tool, parent = self.ServerSettingsDialog)
  3086.                 
  3087.  
  3088.         time.sleep(1)
  3089.         self.reconnect()
  3090.         
  3091.         try:
  3092.             self.fillServerTab()
  3093.         except:
  3094.             nonfatalException()
  3095.  
  3096.  
  3097.     
  3098.     def on_problems_button_clicked(self, *args):
  3099.         if not self.__dict__.has_key('troubleshooter'):
  3100.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit, parent = self.ServerSettingsDialog)
  3101.         
  3102.  
  3103.     
  3104.     def on_new_printer_activate(self, widget):
  3105.         self.busy(self.PrintersWindow)
  3106.         self.newPrinterGUI.init('printer')
  3107.         self.ready(self.PrintersWindow)
  3108.  
  3109.     
  3110.     def on_autodetected_printer_without_driver(self, widget):
  3111.         self.busy(self.PrintersWindow)
  3112.         self.newPrinterGUI.init('printer_with_uri')
  3113.         self.ready(self.PrintersWindow)
  3114.  
  3115.     
  3116.     def on_new_class_activate(self, widget):
  3117.         self.newPrinterGUI.init('class')
  3118.  
  3119.     
  3120.     def on_btnSelectDevice_clicked(self, button):
  3121.         self.busy(self.PrintersWindow)
  3122.         self.newPrinterGUI.init('device')
  3123.         self.ready(self.PrintersWindow)
  3124.  
  3125.     
  3126.     def on_btnChangePPD_clicked(self, button):
  3127.         self.busy(self.PrintersWindow)
  3128.         self.newPrinterGUI.init('ppd')
  3129.         self.ready(self.PrintersWindow)
  3130.  
  3131.     
  3132.     def checkNPName(self, name):
  3133.         if not name:
  3134.             return False
  3135.         name = unicode(name.lower())
  3136.         for printer in self.printers.values():
  3137.             if not (printer.discovered) and printer.name.lower() == name:
  3138.                 return False
  3139.         
  3140.         return True
  3141.  
  3142.     
  3143.     def makeNameUnique(self, name):
  3144.         '''Make a suggested queue name valid and unique.'''
  3145.         name = name.replace(' ', '-')
  3146.         name = name.replace('/', '-')
  3147.         name = name.replace('#', '-')
  3148.         if not self.checkNPName(name):
  3149.             suffix = 2
  3150.             while not self.checkNPName(name + '-' + str(suffix)):
  3151.                 suffix += 1
  3152.                 if suffix == 100:
  3153.                     break
  3154.                     continue
  3155.             name += '-' + str(suffix)
  3156.         
  3157.         return name
  3158.  
  3159.     
  3160.     def printer_added_or_removed(self):
  3161.         gtk.gdk.threads_enter()
  3162.         self.populateList(prompt_allowed = False)
  3163.         gtk.gdk.threads_leave()
  3164.  
  3165.     
  3166.     def printer_added(self, mon, printer):
  3167.         monitor.Watcher.printer_added(self, mon, printer)
  3168.         self.printer_added_or_removed()
  3169.  
  3170.     
  3171.     def printer_event(self, mon, printer, eventname, event):
  3172.         monitor.Watcher.printer_event(self, mon, printer, eventname, event)
  3173.         
  3174.         def deferred_refresh():
  3175.             self.populateList()
  3176.             return False
  3177.  
  3178.         gtk.gdk.threads_enter()
  3179.         if self.printers.has_key(printer):
  3180.             self.printers[printer].update(**event)
  3181.             self.dests_iconview_selection_changed(self.dests_iconview)
  3182.             gobject.idle_add(deferred_refresh)
  3183.             if self.PrinterPropertiesDialog.get_property('visible'):
  3184.                 self.printer.getAttributes()
  3185.                 self.updatePrinterProperties()
  3186.             
  3187.         
  3188.         gtk.gdk.threads_leave()
  3189.  
  3190.     
  3191.     def printer_removed(self, mon, printer):
  3192.         monitor.Watcher.printer_removed(self, mon, printer)
  3193.         self.printer_added_or_removed()
  3194.  
  3195.     
  3196.     def state_reason_added(self, mon, reason):
  3197.         monitor.Watcher.state_reason_added(self, mon, reason)
  3198.         gtk.gdk.threads_enter()
  3199.         if self.PrinterPropertiesDialog.get_property('visible'):
  3200.             self.printer.getAttributes()
  3201.             self.updatePrinterProperties()
  3202.         
  3203.         gtk.gdk.threads_leave()
  3204.  
  3205.     
  3206.     def state_reason_removed(self, mon, reason):
  3207.         monitor.Watcher.state_reason_removed(self, mon, reason)
  3208.         gtk.gdk.threads_enter()
  3209.         if self.PrinterPropertiesDialog.get_property('visible'):
  3210.             self.printer.getAttributes()
  3211.             self.updatePrinterProperties()
  3212.         
  3213.         gtk.gdk.threads_leave()
  3214.  
  3215.     
  3216.     def cups_connection_error(self, mon):
  3217.         monitor.Watcher.cups_connection_error(self, mon)
  3218.         
  3219.         try:
  3220.             self.cups.getClasses()
  3221.         except:
  3222.             self.cups = None
  3223.             gtk.gdk.threads_enter()
  3224.             self.setConnected()
  3225.             self.populateList(prompt_allowed = False)
  3226.             gtk.gdk.threads_leave()
  3227.  
  3228.  
  3229.  
  3230.  
  3231. class NewPrinterGUI(GtkGUI):
  3232.     new_printer_device_tabs = {
  3233.         'parallel': 0,
  3234.         'usb': 0,
  3235.         'bluetooth': 0,
  3236.         'hal': 0,
  3237.         'beh': 0,
  3238.         'hp': 0,
  3239.         'hpfax': 0,
  3240.         'dnssd': 0,
  3241.         'socket': 2,
  3242.         'ipp': 3,
  3243.         'http': 3,
  3244.         'https': 3,
  3245.         'lpd': 4,
  3246.         'scsi': 5,
  3247.         'serial': 6,
  3248.         'smb': 7,
  3249.         'network': 8 }
  3250.     DOWNLOADABLE_ONLYPPD = True
  3251.     HP_PLUGIN_SUPPORT = True
  3252.     
  3253.     def __init__(self, mainapp):
  3254.         self.mainapp = mainapp
  3255.         self.language = mainapp.language
  3256.         self.options = { }
  3257.         self.changed = set()
  3258.         self.conflicts = set()
  3259.         self.device = None
  3260.         self.ppd = None
  3261.         self.remotecupsqueue = False
  3262.         self.exactdrivermatch = False
  3263.         self.installable_options = False
  3264.         self.jockey_installed_files = []
  3265.         self.jockey_lock = thread.allocate_lock()
  3266.         self.ppds_lock = thread.allocate_lock()
  3267.         self.ppds_queried = False
  3268.         self.drivers_lock = thread.allocate_lock()
  3269.         self.getWidgets({
  3270.             'NewPrinterWindow': [
  3271.                 'NewPrinterWindow',
  3272.                 'ntbkNewPrinter',
  3273.                 'btnNPBack',
  3274.                 'btnNPForward',
  3275.                 'btnNPApply',
  3276.                 'imgProcessWorking',
  3277.                 'entNPName',
  3278.                 'entNPDescription',
  3279.                 'entNPLocation',
  3280.                 'tvNPDevices',
  3281.                 'ntbkNPType',
  3282.                 'lblNPDeviceDescription',
  3283.                 'expNPDeviceURIs',
  3284.                 'tvNPDeviceURIs',
  3285.                 'cmbNPTSerialBaud',
  3286.                 'cmbNPTSerialParity',
  3287.                 'cmbNPTSerialBits',
  3288.                 'cmbNPTSerialFlow',
  3289.                 'btnNPTLpdProbe',
  3290.                 'cmbentNPTLpdHost',
  3291.                 'cmbentNPTLpdQueue',
  3292.                 'entNPTIPPHostname',
  3293.                 'lblIPPURI',
  3294.                 'entNPTIPPQueuename',
  3295.                 'btnIPPVerify',
  3296.                 'entNPTDirectJetHostname',
  3297.                 'entNPTDirectJetPort',
  3298.                 'entSMBURI',
  3299.                 'btnSMBBrowse',
  3300.                 'tblSMBAuth',
  3301.                 'rbtnSMBAuthPrompt',
  3302.                 'rbtnSMBAuthSet',
  3303.                 'entSMBUsername',
  3304.                 'entSMBPassword',
  3305.                 'btnSMBVerify',
  3306.                 'entNPTNetworkHostname',
  3307.                 'btnNetworkFind',
  3308.                 'lblNetworkFindSearching',
  3309.                 'lblNetworkFindNotFound',
  3310.                 'entNPTDevice',
  3311.                 'tvNCMembers',
  3312.                 'tvNCNotMembers',
  3313.                 'btnNCAddMember',
  3314.                 'btnNCDelMember',
  3315.                 'ntbkPPDSource',
  3316.                 'rbtnNPPPD',
  3317.                 'tvNPMakes',
  3318.                 'rbtnNPFoomatic',
  3319.                 'filechooserPPD',
  3320.                 'rbtnNPDownloadableDriverSearch',
  3321.                 'entNPDownloadableDriverSearch',
  3322.                 'btnNPDownloadableDriverSearch',
  3323.                 'cmbNPDownloadableDriverFoundPrinters',
  3324.                 'tvNPModels',
  3325.                 'tvNPDrivers',
  3326.                 'rbtnChangePPDasIs',
  3327.                 'rbtnChangePPDKeepSettings',
  3328.                 'scrNPInstallableOptions',
  3329.                 'vbNPInstallOptions',
  3330.                 'tvNPDownloadableDrivers',
  3331.                 'ntbkNPDownloadableDriverProperties',
  3332.                 'lblNPDownloadableDriverSupplier',
  3333.                 'cbNPDownloadableDriverSupplierVendor',
  3334.                 'lblNPDownloadableDriverLicense',
  3335.                 'cbNPDownloadableDriverLicensePatents',
  3336.                 'cbNPDownloadableDriverLicenseFree',
  3337.                 'lblNPDownloadableDriverDescription',
  3338.                 'lblNPDownloadableDriverSupportContacts',
  3339.                 'hsDownloadableDriverPerfText',
  3340.                 'hsDownloadableDriverPerfLineArt',
  3341.                 'hsDownloadableDriverPerfGraphics',
  3342.                 'hsDownloadableDriverPerfPhoto',
  3343.                 'lblDownloadableDriverPerfTextUnknown',
  3344.                 'lblDownloadableDriverPerfLineArtUnknown',
  3345.                 'lblDownloadableDriverPerfGraphicsUnknown',
  3346.                 'lblDownloadableDriverPerfPhotoUnknown',
  3347.                 'frmNPDownloadableDriverLicenseTerms',
  3348.                 'tvNPDownloadableDriverLicense',
  3349.                 'rbtnNPDownloadLicenseYes',
  3350.                 'rbtnNPDownloadLicenseNo'],
  3351.             'WaitWindow': [
  3352.                 'WaitWindow',
  3353.                 'lblWait'],
  3354.             'SMBBrowseDialog': [
  3355.                 'SMBBrowseDialog',
  3356.                 'tvSMBBrowser',
  3357.                 'btnSMBBrowseOk'],
  3358.             'InstallDialog': [
  3359.                 'InstallDialog',
  3360.                 'lblInstall'] })
  3361.         for dialog in [
  3362.             self.SMBBrowseDialog]:
  3363.             dialog.connect('delete-event', on_delete_just_hide)
  3364.         
  3365.         self.busy = mainapp.busy
  3366.         self.ready = mainapp.ready
  3367.         gtk_label_autowrap.set_autowrap(self.NewPrinterWindow)
  3368.         self.ntbkNewPrinter.set_show_tabs(False)
  3369.         self.ntbkPPDSource.set_show_tabs(False)
  3370.         self.ntbkNPType.set_show_tabs(False)
  3371.         self.ntbkNPDownloadableDriverProperties.set_show_tabs(False)
  3372.         self.spinner = gtkspinner.Spinner(self.imgProcessWorking)
  3373.         self.openprinting = cupshelpers.openprinting.OpenPrinting()
  3374.         self.openprinting_query_handle = None
  3375.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3376.         cell = gtk.CellRendererText()
  3377.         combobox.pack_start(cell, True)
  3378.         combobox.add_attribute(cell, 'text', 0)
  3379.         if self.DOWNLOADABLE_ONLYPPD:
  3380.             for widget in [
  3381.                 self.cbNPDownloadableDriverLicenseFree,
  3382.                 self.cbNPDownloadableDriverLicensePatents]:
  3383.                 widget.hide()
  3384.             
  3385.         
  3386.         
  3387.         def protect_toggle(toggle_widget):
  3388.             active = toggle_widget.get_data('protect_active')
  3389.             if active != None:
  3390.                 toggle_widget.set_active(active)
  3391.             
  3392.  
  3393.         for widget in [
  3394.             self.cbNPDownloadableDriverSupplierVendor,
  3395.             self.cbNPDownloadableDriverLicenseFree,
  3396.             self.cbNPDownloadableDriverLicensePatents]:
  3397.             widget.connect('clicked', protect_toggle)
  3398.         
  3399.         for widget in [
  3400.             self.hsDownloadableDriverPerfText,
  3401.             self.hsDownloadableDriverPerfLineArt,
  3402.             self.hsDownloadableDriverPerfGraphics,
  3403.             self.hsDownloadableDriverPerfPhoto]:
  3404.             widget.connect('change-value', (lambda x, y, z: True))
  3405.         
  3406.         slct = self.tvNPDevices.get_selection()
  3407.         slct.set_select_function(self.device_select_function)
  3408.         self.tvNPDevices.set_row_separator_func(self.device_row_separator_fn)
  3409.         self.tvNPDevices.connect('row-activated', self.device_row_activated)
  3410.         self.expNPDeviceURIs.connect('notify::expanded', self.on_expNPDeviceURIs_expanded)
  3411.         self.smb_store = gtk.TreeStore(gobject.TYPE_PYOBJECT)
  3412.         self.btnSMBBrowse.set_sensitive(PYSMB_AVAILABLE)
  3413.         if not PYSMB_AVAILABLE:
  3414.             self.btnSMBBrowse.set_tooltip_text(_('Browsing not available (pysmbc not installed)'))
  3415.         
  3416.         self.tvSMBBrowser.set_model(self.smb_store)
  3417.         col = gtk.TreeViewColumn(_('Share'))
  3418.         cell = gtk.CellRendererText()
  3419.         col.pack_start(cell, False)
  3420.         col.set_cell_data_func(cell, self.smbbrowser_cell_share)
  3421.         self.tvSMBBrowser.append_column(col)
  3422.         col = gtk.TreeViewColumn(_('Comment'))
  3423.         cell = gtk.CellRendererText()
  3424.         col.pack_start(cell, False)
  3425.         col.set_cell_data_func(cell, self.smbbrowser_cell_comment)
  3426.         self.tvSMBBrowser.append_column(col)
  3427.         slct = self.tvSMBBrowser.get_selection()
  3428.         slct.set_select_function(self.smb_select_function)
  3429.         self.SMBBrowseDialog.set_transient_for(self.NewPrinterWindow)
  3430.         self.tvNPDrivers.set_has_tooltip(True)
  3431.         self.tvNPDrivers.connect('query-tooltip', self.on_NPDrivers_query_tooltip)
  3432.         ppd_filter = gtk.FileFilter()
  3433.         ppd_filter.set_name(_('PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *.PPD.GZ)'))
  3434.         ppd_filter.add_pattern('*.ppd')
  3435.         ppd_filter.add_pattern('*.PPD')
  3436.         ppd_filter.add_pattern('*.ppd.gz')
  3437.         ppd_filter.add_pattern('*.PPD.gz')
  3438.         ppd_filter.add_pattern('*.PPD.GZ')
  3439.         self.filechooserPPD.add_filter(ppd_filter)
  3440.         ppd_filter = gtk.FileFilter()
  3441.         ppd_filter.set_name(_('All files (*)'))
  3442.         ppd_filter.add_pattern('*')
  3443.         self.filechooserPPD.add_filter(ppd_filter)
  3444.  
  3445.     
  3446.     def show_IPP_Error(self, exception, message):
  3447.         return show_IPP_Error(exception, message, parent = self.NewPrinterWindow)
  3448.  
  3449.     
  3450.     def option_changed(self, option):
  3451.         if option.is_changed():
  3452.             self.changed.add(option)
  3453.         else:
  3454.             self.changed.discard(option)
  3455.         if option.conflicts:
  3456.             self.conflicts.add(option)
  3457.         else:
  3458.             self.conflicts.discard(option)
  3459.         self.setDataButtonState()
  3460.  
  3461.     
  3462.     def setDataButtonState(self):
  3463.         self.btnNPForward.set_sensitive(not bool(self.conflicts))
  3464.  
  3465.     
  3466.     def init(self, dialog_mode):
  3467.         self.dialog_mode = dialog_mode
  3468.         self.options = { }
  3469.         self.changed = set()
  3470.         self.conflicts = set()
  3471.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3472.         combobox.set_model(gtk.ListStore(str, str))
  3473.         self.entNPDownloadableDriverSearch.set_text('')
  3474.         button = self.btnNPDownloadableDriverSearch
  3475.         label = button.get_children()[0].get_children()[0].get_children()[1]
  3476.         self.btnNPDownloadableDriverSearch_label = label
  3477.         label.set_text(_('Search'))
  3478.         if self.dialog_mode in ('printer', 'printer_with_uri', 'class'):
  3479.             if self.dialog_mode == 'class':
  3480.                 name_proto = 'class'
  3481.             else:
  3482.                 name_proto = 'printer'
  3483.             self.entNPName.set_text(self.mainapp.makeNameUnique(name_proto))
  3484.             self.entNPName.grab_focus()
  3485.             for widget in [
  3486.                 self.entNPLocation,
  3487.                 self.entNPDescription,
  3488.                 self.entSMBURI,
  3489.                 self.entSMBUsername,
  3490.                 self.entSMBPassword]:
  3491.                 widget.set_text('')
  3492.             
  3493.         
  3494.         if self.dialog_mode == 'printer_with_uri':
  3495.             device_dict = { }
  3496.             self.device = cupshelpers.Device(self.mainapp.device_uri, **device_dict)
  3497.         
  3498.         self.entNPTDirectJetPort.set_text('9100')
  3499.         self.rbtnSMBAuthPrompt.set_active(True)
  3500.         if self.dialog_mode == 'printer':
  3501.             self.NewPrinterWindow.set_title(_('New Printer'))
  3502.             self.ntbkNewPrinter.set_current_page(1)
  3503.             self.fillDeviceTab()
  3504.             self.rbtnNPFoomatic.set_active(True)
  3505.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3506.             self.new_printer_PPDs_loaded = False
  3507.             self.queryPPDs()
  3508.         elif self.dialog_mode == 'class':
  3509.             self.NewPrinterWindow.set_title(_('New Class'))
  3510.             self.fillNewClassMembers()
  3511.             self.ntbkNewPrinter.set_current_page(0)
  3512.         elif self.dialog_mode == 'device':
  3513.             self.NewPrinterWindow.set_title(_('Change Device URI'))
  3514.             self.ntbkNewPrinter.set_current_page(1)
  3515.             self.fillDeviceTab(self.mainapp.printer.device_uri)
  3516.         elif self.dialog_mode == 'ppd' or self.dialog_mode == 'printer_with_uri':
  3517.             if self.dialog_mode == 'ppd':
  3518.                 self.NewPrinterWindow.set_title(_('Change Driver'))
  3519.             else:
  3520.                 self.NewPrinterWindow.set_title(_('New Printer'))
  3521.             self.ntbkNewPrinter.set_current_page(2)
  3522.             self.rbtnNPFoomatic.set_active(True)
  3523.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3524.             self.rbtnChangePPDKeepSettings.set_active(True)
  3525.             self.auto_model = ''
  3526.             ppd = self.mainapp.ppd
  3527.             devid = self.mainapp.devid
  3528.             if devid != '':
  3529.                 
  3530.                 try:
  3531.                     devid_dict = cupshelpers.parseDeviceID(devid)
  3532.                     self.loadPPDs()
  3533.                     reloaded = 0
  3534.                     while reloaded < 2:
  3535.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID(devid_dict['MFG'], devid_dict['MDL'], devid_dict['DES'], devid_dict['CMD'], uri, self.jockey_installed_files)
  3536.                         if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3537.                             
  3538.                             try:
  3539.                                 if self.fetchJockeyDriver():
  3540.                                     
  3541.                                     try:
  3542.                                         self.dropPPDs()
  3543.                                         self.loadPPDs()
  3544.                                         reloaded = 1
  3545.                                     reloaded = 2
  3546.  
  3547.                                 else:
  3548.                                     reloaded = 2
  3549.                             reloaded = 2
  3550.  
  3551.                             continue
  3552.                         reloaded = 2
  3553.                     if ppdname:
  3554.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3555.                         make_model = ppddict['ppd-make-and-model']
  3556.                         (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  3557.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  3558.                             self.exactdrivermatch = True
  3559.                             self.fillMakeList()
  3560.                             self.ntbkNewPrinter.set_current_page(6)
  3561.                             self.nextNPTab(step = 0)
  3562.                         else:
  3563.                             self.exactdrivermatch = False
  3564.                     else:
  3565.                         self.auto_make = devid_dict['MFG']
  3566.                         self.auto_model = devid_dict['MDL']
  3567.                 except:
  3568.                     None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3569.                     self.auto_make = devid_dict['MFG']
  3570.                     self.auto_model = devid_dict['MDL']
  3571.  
  3572.                 if not (self.device) or not (self.device.id):
  3573.                     self.device.id = devid
  3574.                     self.device.id_dict = cupshelpers.parseDeviceID(self.device.id)
  3575.                 
  3576.                 self.mainapp.devid = ''
  3577.             elif ppd:
  3578.                 attr = ppd.findAttr('Manufacturer')
  3579.                 if attr:
  3580.                     mfr = attr.value
  3581.                 else:
  3582.                     mfr = ''
  3583.                 makeandmodel = mfr
  3584.                 attr = ppd.findAttr('ModelName')
  3585.                 if not attr:
  3586.                     attr = ppd.findAttr('ShortNickName')
  3587.                 
  3588.                 if not attr:
  3589.                     attr = ppd.findAttr('NickName')
  3590.                 
  3591.                 if attr:
  3592.                     if attr.value.startswith(mfr):
  3593.                         makeandmodel = attr.value
  3594.                     else:
  3595.                         makeandmodel += ' ' + attr.value
  3596.                 else:
  3597.                     makeandmodel = ''
  3598.                 (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(makeandmodel)
  3599.             else:
  3600.                 self.auto_make = 'Raw'
  3601.                 self.auto_model = 'Queue'
  3602.             
  3603.             try:
  3604.                 if self.dialog_mode == 'ppd':
  3605.                     parent = self.mainapp.PrinterPropertiesDialog
  3606.                 else:
  3607.                     parent = self.NewPrinterWindow
  3608.                 self.loadPPDs(parent = parent)
  3609.             except cups.IPPError:
  3610.                 None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3611.                 (e, m) = None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3612.                 show_IPP_Error(e, m, parent = self.mainapp.PrintersWindow)
  3613.                 return None
  3614.                 return None
  3615.  
  3616.             self.fillMakeList()
  3617.         
  3618.         self.setNPButtons()
  3619.         self.NewPrinterWindow.show()
  3620.  
  3621.     
  3622.     def queryJockeyDriver(self):
  3623.         debugprint('queryJockeyDriver')
  3624.         if not self.jockey_lock.acquire(0):
  3625.             debugprint('queryJockeyDriver: in progress')
  3626.             return None
  3627.         debugprint('Lock acquired for Jockey driver thread')
  3628.         devid = ''
  3629.         
  3630.         try:
  3631.             devid = self.device.id
  3632.         except:
  3633.             self.jockey_lock.acquire(0)
  3634.  
  3635.         if devid == '':
  3636.             self.jockey_lock.release()
  3637.             return None
  3638.         thread.start_new_thread(self.getJockeyDriver_thread, (devid,))
  3639.         debugprint('Jockey driver thread started')
  3640.  
  3641.     
  3642.     def getJockeyDriver_thread(self, id):
  3643.         debugprint('Requesting driver from Jockey: %s' % id)
  3644.         self.jockey_driver_result = False
  3645.         self.jockey_installed_files = []
  3646.         
  3647.         try:
  3648.             bus = dbus.SessionBus()
  3649.             obj = bus.get_object('com.ubuntu.DeviceDriver', '/GUI')
  3650.             jockeyloader = dbus.Interface(obj, 'com.ubuntu.DeviceDriver')
  3651.             (result, installedfiles) = jockeyloader.search_driver('printer_deviceid:%s' % id, timeout = 999999)
  3652.             self.jockey_driver_result = result
  3653.             self.jockey_installed_files = installedfiles
  3654.             if result:
  3655.                 debugprint('New driver downloaded and installed')
  3656.             else:
  3657.                 debugprint('No new driver found or download rejected')
  3658.         except dbus.DBusException:
  3659.             e = None
  3660.             self.jockey_driver_result = e
  3661.             debugprint(self.jockey_driver_result)
  3662.         except Exception:
  3663.             e = None
  3664.             nonfatalException()
  3665.             self.jockey_driver_result = e
  3666.             debugprint('Non-D-Bus error on Jockey call: %s' % e)
  3667.  
  3668.         debugprint('Releasing Jockey driver lock')
  3669.         self.jockey_lock.release()
  3670.  
  3671.     
  3672.     def fetchJockeyDriver(self, parent = None):
  3673.         debugprint('fetchJockeyDriver')
  3674.         self.queryJockeyDriver()
  3675.         time.sleep(0.01)
  3676.         waiting = False
  3677.         while self.jockey_lock.locked():
  3678.             if not waiting:
  3679.                 waiting = True
  3680.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for downloadable drivers'))
  3681.                 if not parent:
  3682.                     parent = self.NewPrinterWindow
  3683.                 
  3684.                 self.WaitWindow.set_transient_for(parent)
  3685.                 self.WaitWindow.show()
  3686.                 self.busy(self.WaitWindow)
  3687.             
  3688.             if self.mainapp.cups == None:
  3689.                 debugprint('CUPS connection lost, reconnecting ...')
  3690.                 
  3691.                 try:
  3692.                     self.mainapp.cups = authconn.Connection(self.mainapp.PrintersWindow)
  3693.                     self.mainapp.setConnected()
  3694.                     debugprint('Reconnected')
  3695.                     self.mainapp.populateList()
  3696.                 except RuntimeError:
  3697.                     debugprint('Reconnection failed')
  3698.                 except:
  3699.                     None<EXCEPTION MATCH>RuntimeError
  3700.                 
  3701.  
  3702.             None<EXCEPTION MATCH>RuntimeError
  3703.             while gtk.events_pending():
  3704.                 gtk.main_iteration()
  3705.             time.sleep(0.1)
  3706.         if waiting:
  3707.             self.WaitWindow.hide()
  3708.         
  3709.         debugprint('Driver download request finished')
  3710.         result = self.jockey_driver_result
  3711.         if isinstance(result, Exception):
  3712.             raise result
  3713.         isinstance(result, Exception)
  3714.         return result
  3715.  
  3716.     
  3717.     def queryPPDs(self):
  3718.         debugprint('queryPPDs')
  3719.         if not self.ppds_lock.acquire(0):
  3720.             debugprint('queryPPDs: in progress')
  3721.             return None
  3722.         debugprint('Lock acquired for PPDs thread')
  3723.         self.ppds_queried = True
  3724.         thread.start_new_thread(self.getPPDs_thread, (self.language[0],))
  3725.         debugprint('PPDs thread started')
  3726.  
  3727.     
  3728.     def getPPDs_thread(self, language):
  3729.         
  3730.         try:
  3731.             debugprint('Connecting (PPDs)')
  3732.             cups.setUser(self.mainapp.connect_user)
  3733.             cups.setPasswordCB((lambda x: ''))
  3734.             c = cups.Connection(host = self.mainapp.connect_server, encryption = self.mainapp.connect_encrypt)
  3735.             debugprint('Fetching PPDs')
  3736.             ppds_dict = c.getPPDs()
  3737.             self.ppds_result = cupshelpers.ppds.PPDs(ppds_dict, language = language)
  3738.             debugprint('Closing connection (PPDs)')
  3739.             del c
  3740.         except cups.IPPError:
  3741.             (e, msg) = None
  3742.             self.ppds_result = cups.IPPError(e, msg)
  3743.         except Exception:
  3744.             e = None
  3745.             nonfatalException()
  3746.             self.ppds_result = e
  3747.  
  3748.         debugprint('Releasing PPDs lock')
  3749.         self.ppds_lock.release()
  3750.  
  3751.     
  3752.     def fetchPPDs(self, parent = None):
  3753.         debugprint('fetchPPDs')
  3754.         if not self.ppds_queried:
  3755.             self.queryPPDs()
  3756.         
  3757.         waiting = False
  3758.         while self.ppds_lock.locked():
  3759.             if not waiting:
  3760.                 waiting = True
  3761.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  3762.                 if not parent:
  3763.                     parent = self.NewPrinterWindow
  3764.                 
  3765.                 self.WaitWindow.set_transient_for(parent)
  3766.                 self.WaitWindow.show()
  3767.                 self.busy(self.WaitWindow)
  3768.             
  3769.             while gtk.events_pending():
  3770.                 gtk.main_iteration()
  3771.             time.sleep(0.1)
  3772.         if waiting:
  3773.             self.WaitWindow.hide()
  3774.         
  3775.         debugprint('Got PPDs')
  3776.         self.ppds_queried = False
  3777.         result = self.ppds_result
  3778.         if isinstance(result, Exception):
  3779.             raise result
  3780.         isinstance(result, Exception)
  3781.         return result
  3782.  
  3783.     
  3784.     def loadPPDs(self, parent = None):
  3785.         
  3786.         try:
  3787.             return self.ppds
  3788.         except:
  3789.             self.ppds = self.fetchPPDs(parent = parent)
  3790.             return self.ppds
  3791.  
  3792.  
  3793.     
  3794.     def dropPPDs(self):
  3795.         
  3796.         try:
  3797.             del self.ppds
  3798.         except:
  3799.             pass
  3800.  
  3801.  
  3802.     
  3803.     def fillNewClassMembers(self):
  3804.         model = self.tvNCMembers.get_model()
  3805.         model.clear()
  3806.         model = self.tvNCNotMembers.get_model()
  3807.         model.clear()
  3808.         for printer in self.mainapp.printers.itervalues():
  3809.             model.append((printer.name,))
  3810.         
  3811.  
  3812.     
  3813.     def on_btnNCAddMember_clicked(self, button):
  3814.         moveClassMembers(self.tvNCNotMembers, self.tvNCMembers)
  3815.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3816.         button.set_sensitive(False)
  3817.  
  3818.     
  3819.     def on_btnNCDelMember_clicked(self, button):
  3820.         moveClassMembers(self.tvNCMembers, self.tvNCNotMembers)
  3821.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3822.         button.set_sensitive(False)
  3823.  
  3824.     
  3825.     def on_tvNCMembers_cursor_changed(self, widget):
  3826.         selection = widget.get_selection()
  3827.         (model_from, rows) = selection.get_selected_rows()
  3828.         self.btnNCDelMember.set_sensitive(rows != [])
  3829.  
  3830.     
  3831.     def on_tvNCNotMembers_cursor_changed(self, widget):
  3832.         selection = widget.get_selection()
  3833.         (model_from, rows) = selection.get_selected_rows()
  3834.         self.btnNCAddMember.set_sensitive(rows != [])
  3835.  
  3836.     
  3837.     def on_NPCancel(self, widget, event = None):
  3838.         self.NewPrinterWindow.hide()
  3839.         if self.openprinting_query_handle != None:
  3840.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  3841.             self.openprinting_query_handle = None
  3842.         
  3843.         return True
  3844.  
  3845.     
  3846.     def on_btnNPBack_clicked(self, widget):
  3847.         self.nextNPTab(-1)
  3848.  
  3849.     
  3850.     def on_btnNPForward_clicked(self, widget):
  3851.         self.nextNPTab()
  3852.  
  3853.     
  3854.     def nextNPTab(self, step = 1):
  3855.         page_nr = self.ntbkNewPrinter.get_current_page()
  3856.         if self.dialog_mode == 'class':
  3857.             order = [
  3858.                 0,
  3859.                 4,
  3860.                 5]
  3861.         elif self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  3862.             self.busy(self.NewPrinterWindow)
  3863.             if page_nr == 1:
  3864.                 (self.auto_make, self.auto_model) = (None, None)
  3865.                 self.device.uri = self.getDeviceURI()
  3866.                 if not self.install_hplip_plugin(self.device.uri):
  3867.                     self.on_NPCancel(None)
  3868.                     return None
  3869.                 uri = self.device.uri
  3870.                 if uri and uri.startswith('smb://'):
  3871.                     uri = SMBURI(uri = uri[6:]).sanitize_uri()
  3872.                 
  3873.                 self.remotecupsqueue = None
  3874.                 res = re.search('ipp://(\\S+(:\\d+|))/printers/(\\S+)', uri)
  3875.                 if res:
  3876.                     resg = res.groups()
  3877.                     
  3878.                     try:
  3879.                         conn = httplib.HTTPConnection(resg[0])
  3880.                         conn.request('GET', '/printers/%s.ppd' % resg[2])
  3881.                         resp = conn.getresponse()
  3882.                         if resp.status == 200:
  3883.                             self.remotecupsqueue = resg[2]
  3884.                     except:
  3885.                         pass
  3886.  
  3887.                     
  3888.                     try:
  3889.                         if len(resg[1]) > 0:
  3890.                             port = int(resg[1])
  3891.                         else:
  3892.                             port = 631
  3893.                         encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
  3894.                         c = cups.Connection(host = resg[0], port = port, encryption = encryption)
  3895.                         r = [
  3896.                             'printer-info',
  3897.                             'printer-location']
  3898.                         attrs = c.getPrinterAttributes(uri = uri, requested_attributes = r)
  3899.                         info = attrs.get('printer-info', '')
  3900.                         location = attrs.get('printer-location', '')
  3901.                         if len(info) > 0:
  3902.                             self.entNPDescription.set_text(info)
  3903.                         
  3904.                         if len(location) > 0:
  3905.                             self.entNPLocation.set_text(location)
  3906.                     except RuntimeError:
  3907.                         pass
  3908.                     except:
  3909.                         None<EXCEPTION MATCH>RuntimeError
  3910.                         nonfatalException()
  3911.                     
  3912.  
  3913.                 None<EXCEPTION MATCH>RuntimeError
  3914.                 res = re.search('(dnssd|mdns)://([^\\./]+)(\\.[^/]+|)/cups', uri)
  3915.                 if res and self.device.id_dict and self.device.id_dict.get('MDL', ''):
  3916.                     resg = res.groups()
  3917.                     self.remotecupsqueue = self.device.info
  3918.                 
  3919.                 if not (self.remotecupsqueue) and not (self.new_printer_PPDs_loaded):
  3920.                     
  3921.                     try:
  3922.                         self.loadPPDs(self.NewPrinterWindow)
  3923.                     except cups.IPPError:
  3924.                         (e, msg) = None
  3925.                         self.ready(self.NewPrinterWindow)
  3926.                         self.show_IPP_Error(e, msg)
  3927.                         return None
  3928.                         self.ready(self.NewPrinterWindow)
  3929.                         return None
  3930.  
  3931.                     self.new_printer_PPDs_loaded = True
  3932.                 
  3933.                 ppdname = None
  3934.                 
  3935.                 try:
  3936.                     if self.remotecupsqueue:
  3937.                         ppdname = 'raw'
  3938.                         self.ppd = ppdname
  3939.                         name = self.remotecupsqueue
  3940.                         name = self.mainapp.makeNameUnique(name)
  3941.                         self.entNPName.set_text(name)
  3942.                     elif (self.device.id or self.device.make_and_model) and self.device.make_and_model != 'Unknown':
  3943.                         if self.device.id:
  3944.                             id_dict = self.device.id_dict
  3945.                         else:
  3946.                             id_dict = { }
  3947.                             (id_dict['MFG'], id_dict['MDL']) = cupshelpers.ppds.ppdMakeModelSplit(self.device.make_and_model)
  3948.                             id_dict['DES'] = ''
  3949.                             id_dict['CMD'] = ()
  3950.                         reloaded = 0
  3951.                         while reloaded < 2:
  3952.                             (status, ppdname) = self.ppds.getPPDNameFromDeviceID(id_dict['MFG'], id_dict['MDL'], id_dict['DES'], id_dict['CMD'], self.device.uri, self.jockey_installed_files)
  3953.                             if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3954.                                 
  3955.                                 try:
  3956.                                     if self.fetchJockeyDriver():
  3957.                                         
  3958.                                         try:
  3959.                                             self.dropPPDs()
  3960.                                             self.loadPPDs()
  3961.                                             reloaded = 1
  3962.                                         reloaded = 2
  3963.  
  3964.                                     else:
  3965.                                         reloaded = 2
  3966.                                 reloaded = 2
  3967.  
  3968.                                 continue
  3969.                             reloaded = 2
  3970.                     else:
  3971.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID('Generic', 'Printer', 'Generic Printer', [], self.device.uri)
  3972.                     if ppdname and not (self.remotecupsqueue):
  3973.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3974.                         make_model = ppddict['ppd-make-and-model']
  3975.                         (make, model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  3976.                         self.auto_make = make
  3977.                         self.auto_model = model
  3978.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  3979.                             self.exactdrivermatch = True
  3980.                         else:
  3981.                             self.exactdrivermatch = False
  3982.                 except:
  3983.                     nonfatalException()
  3984.  
  3985.                 if not self.remotecupsqueue:
  3986.                     self.fillMakeList()
  3987.                 
  3988.             elif page_nr == 3:
  3989.                 if not self.device.id:
  3990.                     
  3991.                     try:
  3992.                         (model, iter) = self.tvNPModels.get_selection().get_selected()
  3993.                         name = model.get(iter, 0)[0]
  3994.                         name = self.mainapp.makeNameUnique(name)
  3995.                         self.entNPName.set_text(name)
  3996.                     nonfatalException()
  3997.  
  3998.                 
  3999.             
  4000.             self.ready(self.NewPrinterWindow)
  4001.             if self.dialog_mode == 'printer':
  4002.                 if self.remotecupsqueue:
  4003.                     order = [
  4004.                         1,
  4005.                         0]
  4006.                 elif self.exactdrivermatch:
  4007.                     order = [
  4008.                         1,
  4009.                         6,
  4010.                         0]
  4011.                 elif self.rbtnNPFoomatic.get_active():
  4012.                     order = [
  4013.                         1,
  4014.                         2,
  4015.                         3,
  4016.                         6,
  4017.                         0]
  4018.                 elif self.rbtnNPPPD.get_active():
  4019.                     order = [
  4020.                         1,
  4021.                         2,
  4022.                         6,
  4023.                         0]
  4024.                 else:
  4025.                     order = [
  4026.                         1,
  4027.                         2,
  4028.                         7,
  4029.                         6,
  4030.                         0]
  4031.             elif self.remotecupsqueue:
  4032.                 order = [
  4033.                     0]
  4034.             elif self.exactdrivermatch:
  4035.                 order = [
  4036.                     6,
  4037.                     0]
  4038.             elif self.rbtnNPFoomatic.get_active():
  4039.                 order = [
  4040.                     2,
  4041.                     3,
  4042.                     6,
  4043.                     0]
  4044.             elif self.rbtnNPPPD.get_active():
  4045.                 order = [
  4046.                     2,
  4047.                     6,
  4048.                     0]
  4049.             else:
  4050.                 order = [
  4051.                     2,
  4052.                     7,
  4053.                     6,
  4054.                     0]
  4055.         elif self.dialog_mode == 'device':
  4056.             order = [
  4057.                 1]
  4058.         elif self.dialog_mode == 'ppd':
  4059.             if self.rbtnNPFoomatic.get_active():
  4060.                 order = [
  4061.                     2,
  4062.                     3,
  4063.                     5,
  4064.                     6]
  4065.             elif self.rbtnNPPPD.get_active():
  4066.                 order = [
  4067.                     2,
  4068.                     5,
  4069.                     6]
  4070.             else:
  4071.                 order = [
  4072.                     2,
  4073.                     7,
  4074.                     5,
  4075.                     6]
  4076.         
  4077.         next_page_nr = order[order.index(page_nr) + step]
  4078.         fetch_ppd = False
  4079.         
  4080.         try:
  4081.             if order.index(5) > -1:
  4082.                 if next_page_nr == 5:
  4083.                     pass
  4084.                 fetch_ppd = step >= 0
  4085.         except ValueError:
  4086.             if next_page_nr == 6:
  4087.                 pass
  4088.             fetch_ppd = step >= 0
  4089.  
  4090.         debugprint('Will fetch ppd? %d' % fetch_ppd)
  4091.         if fetch_ppd:
  4092.             self.ppd = self.getNPPPD()
  4093.             self.installable_options = False
  4094.             if self.ppd == None:
  4095.                 return None
  4096.             if isinstance(self.ppd, cups.PPD):
  4097.                 self.fillNPInstallableOptions()
  4098.             else:
  4099.                 ppd = self.ppd
  4100.                 self.ppd = None
  4101.                 self.fillNPInstallableOptions()
  4102.                 self.ppd = ppd
  4103.             if not self.installable_options:
  4104.                 if next_page_nr == 6:
  4105.                     next_page_nr = order[order.index(next_page_nr) + 1]
  4106.                 
  4107.             
  4108.         
  4109.         if next_page_nr == 6 and not (self.installable_options) and step < 0:
  4110.             next_page_nr = order[order.index(next_page_nr) - 1]
  4111.         
  4112.         if step >= 0 and next_page_nr == 7:
  4113.             if self.drivers_lock.locked():
  4114.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  4115.                 self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  4116.                 self.WaitWindow.show()
  4117.                 self.busy(self.WaitWindow)
  4118.                 self.busy(self.NewPrinterWindow)
  4119.                 while self.drivers_lock.locked():
  4120.                     while gtk.events_pending():
  4121.                         gtk.main_iteration()
  4122.                     time.sleep(0.1)
  4123.                 self.ready(self.NewPrinterWindow)
  4124.                 self.WaitWindow.hide()
  4125.             
  4126.             self.fillDownloadableDrivers()
  4127.         
  4128.         if step >= 0 and next_page_nr == 0:
  4129.             name = None
  4130.             descr = None
  4131.             
  4132.             try:
  4133.                 if self.device.id and self.device.type not in ('socket', 'lpd', 'ipp', 'http', 'https', 'bluetooth'):
  4134.                     name = '%s %s' % (self.device.id_dict['MFG'], self.device.id_dict['MDL'])
  4135.                     descr = '%s %s' % (self.device.id_dict['MFG'], self.device.id_dict['MDL'])
  4136.             except:
  4137.                 nonfatalException()
  4138.  
  4139.             
  4140.             try:
  4141.                 if name == None and isinstance(self.ppd, cups.PPD):
  4142.                     mname = self.ppd.findAttr('modelName').value
  4143.                     (make, model) = cupshelpers.ppds.ppdMakeModelSplit(mname)
  4144.                     name = '%s %s' % (make, model)
  4145.                     descr = '%s %s' % (make, model)
  4146.             except:
  4147.                 nonfatalException()
  4148.  
  4149.             if name == None:
  4150.                 name = 'printer'
  4151.             
  4152.             name = self.mainapp.makeNameUnique(name)
  4153.             self.entNPName.set_text(name)
  4154.             if self.entNPDescription.get_text() == '' and descr:
  4155.                 self.entNPDescription.set_text(descr)
  4156.             
  4157.         
  4158.         self.ntbkNewPrinter.set_current_page(next_page_nr)
  4159.         self.setNPButtons()
  4160.  
  4161.     
  4162.     def setNPButtons(self):
  4163.         nr = self.ntbkNewPrinter.get_current_page()
  4164.         if self.dialog_mode == 'device':
  4165.             self.btnNPBack.hide()
  4166.             self.btnNPForward.hide()
  4167.             self.btnNPApply.show()
  4168.             
  4169.             try:
  4170.                 uri = self.getDeviceURI()
  4171.                 valid = validDeviceURI(uri)
  4172.             except AttributeError:
  4173.                 valid = False
  4174.  
  4175.             self.btnNPApply.set_sensitive(valid)
  4176.             return None
  4177.         self.btnNPForward.show()
  4178.         self.btnNPApply.hide()
  4179.         if nr == 2:
  4180.             downloadable_selected = False
  4181.             if self.rbtnNPDownloadableDriverSearch.get_active():
  4182.                 combobox = self.cmbNPDownloadableDriverFoundPrinters
  4183.                 iter = combobox.get_active_iter()
  4184.                 if iter and combobox.get_model().get_value(iter, 1):
  4185.                     downloadable_selected = True
  4186.                 
  4187.             
  4188.             if not self.rbtnNPFoomatic.get_active() and self.filechooserPPD.get_filename():
  4189.                 pass
  4190.             self.btnNPForward.set_sensitive(bool(downloadable_selected))
  4191.             if self.dialog_mode == 'printer_with_uri':
  4192.                 self.btnNPBack.hide()
  4193.             
  4194.         
  4195.         if nr == 3:
  4196.             (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  4197.             self.btnNPForward.set_sensitive(bool(iter))
  4198.         
  4199.         if nr == 4:
  4200.             self.btnNPForward.hide()
  4201.             self.btnNPApply.show()
  4202.             self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  4203.         
  4204.         if nr == 6:
  4205.             if self.dialog_mode == 'printer_with_uri' and self.exactdrivermatch:
  4206.                 self.btnNPBack.hide()
  4207.             
  4208.         
  4209.         if nr == 7:
  4210.             if self.ntbkNPDownloadableDriverProperties.get_current_page() == 1:
  4211.                 accepted = self.rbtnNPDownloadLicenseYes.get_active()
  4212.             else:
  4213.                 treeview = self.tvNPDownloadableDrivers
  4214.                 (model, iter) = treeview.get_selection().get_selected()
  4215.                 accepted = iter != None
  4216.             self.btnNPForward.set_sensitive(accepted)
  4217.         
  4218.  
  4219.     
  4220.     def on_entNPName_changed(self, widget):
  4221.         text = unicode(widget.get_text())
  4222.         new_text = text
  4223.         new_text = new_text.replace('/', '')
  4224.         new_text = new_text.replace('#', '')
  4225.         new_text = new_text.replace(' ', '')
  4226.         if text != new_text:
  4227.             widget.set_text(new_text)
  4228.         
  4229.         if self.dialog_mode == 'printer':
  4230.             self.btnNPApply.set_sensitive(self.mainapp.checkNPName(new_text))
  4231.         else:
  4232.             self.btnNPForward.set_sensitive(self.mainapp.checkNPName(new_text))
  4233.  
  4234.     
  4235.     def fetchDevices(self, parent = None):
  4236.         debugprint('fetchDevices')
  4237.         self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for printers'))
  4238.         if parent == None:
  4239.             parent = self.mainapp.PrintersWindow
  4240.         
  4241.         self.WaitWindow.set_transient_for(parent)
  4242.         self.WaitWindow.show_now()
  4243.         self.busy(self.WaitWindow)
  4244.         while gtk.events_pending():
  4245.             gtk.main_iteration()
  4246.         debugprint('Fetching devices')
  4247.         self.mainapp.cups._begin_operation(_('fetching device list'))
  4248.         
  4249.         try:
  4250.             devices = cupshelpers.getDevices(self.mainapp.cups)
  4251.         except:
  4252.             self.mainapp.cups._end_operation()
  4253.             self.WaitWindow.hide()
  4254.             raise 
  4255.  
  4256.         self.mainapp.cups._end_operation()
  4257.         self.WaitWindow.hide()
  4258.         debugprint('Got devices')
  4259.         return devices
  4260.  
  4261.     
  4262.     def install_hplip_plugin(self, uri):
  4263.         '''
  4264.         Attempt to install a plugin using hp-plugin.
  4265.  
  4266.         @return: True if plugin not needed (or needed and installed),
  4267.         False on error.
  4268.         '''
  4269.         if not self.HP_PLUGIN_SUPPORT:
  4270.             return True
  4271.         os.environ['URI'] = uri
  4272.         cmd = 'LC_ALL=C DISPLAY= hp-info -x -i -d"${URI}"'
  4273.         debugprint(uri + ': ' + cmd)
  4274.         
  4275.         try:
  4276.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4277.             (stdout, stderr) = p.communicate()
  4278.             if p.returncode != 0:
  4279.                 return True
  4280.         except:
  4281.             self.HP_PLUGIN_SUPPORT
  4282.             return True
  4283.  
  4284.         plugin_needed = -1
  4285.         plugin_reason = -1
  4286.         fw_download = -1
  4287.         hpmodel = None
  4288.         hplip_version = None
  4289.         for line in stdout.split('\n'):
  4290.             if line.find('plugin ') >= 0:
  4291.                 res = re.search('(\\d+)', line)
  4292.                 if res:
  4293.                     resg = res.groups()
  4294.                     plugin_needed = int(resg[0])
  4295.                 
  4296.             elif line.find('plugin-reason') >= 0:
  4297.                 res = re.search('(\\d+)', line)
  4298.                 if res:
  4299.                     resg = res.groups()
  4300.                     plugin_reason = int(resg[0])
  4301.                 
  4302.             elif line.find('fw-download') >= 0:
  4303.                 if line.find('True') >= 0:
  4304.                     fw_download = 1
  4305.                 elif line.find('False') >= 0:
  4306.                     fw_download = 0
  4307.                 
  4308.             elif line.find('model') >= 0:
  4309.                 res = re.search('^\\s*model\\s*(\\S+)\\s*$', line)
  4310.                 if res:
  4311.                     resg = res.groups()
  4312.                     hpmodel = resg[0]
  4313.                 
  4314.             elif line.find('HP Linux Imaging and Printing') >= 0:
  4315.                 res = re.search('(\\d+\\.\\d+\\.\\d+\\w*)', line)
  4316.                 if res:
  4317.                     resg = res.groups()
  4318.                     hplip_version = resg[0]
  4319.                 
  4320.             
  4321.             if plugin_needed >= 0 and plugin_reason >= 0 and fw_download >= 0 and hpmodel != None:
  4322.                 break
  4323.                 continue
  4324.         
  4325.         if plugin_needed <= 0 and not hplip_version or not hpmodel:
  4326.             return True
  4327.         if hplip_version.startswith('3'):
  4328.             os.environ['hp_model'] = hpmodel
  4329.             cmd = 'LC_ALL=C hp-mkuri -c'
  4330.             debugprint(uri + ': ' + hpmodel)
  4331.             
  4332.             try:
  4333.                 p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4334.                 (stdout, stderr) = p.communicate()
  4335.                 if p.returncode < 2:
  4336.                     return True
  4337.             return True
  4338.  
  4339.         elif glob.glob('/usr/share/hplip/data/plugin/*%s*plugin*' % hplip_version):
  4340.             if hplip_version.startswith('2'):
  4341.                 
  4342.                 try:
  4343.                     f = open('/etc/hp/hplip.conf', 'r')
  4344.                     for line in f:
  4345.                         if line.strip().startswith('plugin') and line.strip().endswith('1'):
  4346.                             f.close()
  4347.                             return True
  4348.                         f.close()
  4349.                 except:
  4350.                     not hpmodel
  4351.  
  4352.                 return True
  4353.             hplip_version.startswith('2')
  4354.         
  4355.         text = _('For this printer a proprietary driver plugin from HP is available.\n')
  4356.         if plugin_needed == 1:
  4357.             text += _('The installation of the plugin is required for your printer to work.\n\n')
  4358.         elif plugin_needed == 2:
  4359.             text += _('Installing the plugin is optional, it completes or enhances the functionality\nof your printer. Without plugin at least basic operations work.\n\n')
  4360.         
  4361.         if plugin_reason > 0:
  4362.             text += _('The plugin provides the following features:\n')
  4363.             if plugin_reason & 1 != 0:
  4364.                 text += _(' - Printing support\n')
  4365.             
  4366.             if plugin_reason & 2 != 0:
  4367.                 text += _(' - Faster printing\n')
  4368.             
  4369.             if plugin_reason & 4 != 0:
  4370.                 text += _(' - Better printout quality\n')
  4371.             
  4372.             if plugin_reason & 8 != 0:
  4373.                 text += _(' - Extra printing features\n')
  4374.             
  4375.             if plugin_reason & 64 != 0:
  4376.                 text += _(' - Scanning support\n')
  4377.             
  4378.             if plugin_reason & 128 != 0:
  4379.                 text += _(' - Faster scanning\n')
  4380.             
  4381.             if plugin_reason & 256 != 0:
  4382.                 text += _(' - Better scanning image quality\n')
  4383.             
  4384.             if plugin_reason & 2048 != 0:
  4385.                 text += _(' - Faxing support\n')
  4386.             
  4387.             if plugin_reason & 4096 != 0:
  4388.                 text += _(' - Extra fax features\n')
  4389.             
  4390.             if plugin_reason & 16384 != 0:
  4391.                 text += _(' - Better Input/Output support\n')
  4392.             
  4393.             if plugin_reason & 32768 != 0:
  4394.                 text += _(' - Extra user interface features\n')
  4395.             
  4396.             if plugin_reason & 65536 != 0:
  4397.                 text += _(' - Other extra features\n')
  4398.             
  4399.             text += '\n'
  4400.         
  4401.         text += 'Do you want to download and install the plugin now?\n'
  4402.         if plugin_needed == 1:
  4403.             text += '\nNOTE: The plugin is required for your printer. If you do not install it, your\nprinter will not work.'
  4404.             buttons = (_('Install plugin'), 1, _('Do not set up printer'), 2, _('Set up without plugin'), 3)
  4405.         else:
  4406.             buttons = (_('Yes'), 1, _('No'), 3)
  4407.         dialog = gtk.Dialog(self.device.info, self.NewPrinterWindow, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons)
  4408.         label = gtk.Label(text)
  4409.         dialog.vbox.pack_start(label, True, True, 0)
  4410.         label.show()
  4411.         button_clicked = dialog.run()
  4412.         dialog.destroy()
  4413.         if button_clicked == 1:
  4414.             cmds = ("if python -c 'import PyQt4.QtGui' 2>/dev/null; then gksu -- hp-plugin -u; else exit 255; fi", "gksu -- xterm -T 'HPLIP Plugin Installation' -sb -rightbar -e hp-plugin -i")
  4415.             
  4416.             try:
  4417.                 install_result = -1
  4418.                 for cmd in cmds:
  4419.                     p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4420.                     (stdout, stderr) = p.communicate()
  4421.                     install_result = p.returncode
  4422.                     if install_result != 255:
  4423.                         break
  4424.                         continue
  4425.                 
  4426.                 if install_result == 0:
  4427.                     return True
  4428.                 return False
  4429.             except OSError:
  4430.                 e = None
  4431.                 debugprint('Execution of hp-plugin failed: %s' % e)
  4432.                 return False
  4433.             
  4434.  
  4435.         None<EXCEPTION MATCH>OSError
  4436.         if button_clicked == 2:
  4437.             return False
  4438.         if button_clicked == 3:
  4439.             return True
  4440.         return False
  4441.  
  4442.     
  4443.     def get_hpfax_device_id(self, faxuri):
  4444.         os.environ['URI'] = faxuri
  4445.         cmd = 'LC_ALL=C DISPLAY= hp-info -x -i -d"${URI}"'
  4446.         debugprint(faxuri + ': ' + cmd)
  4447.         
  4448.         try:
  4449.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4450.             (stdout, stderr) = p.communicate()
  4451.         except:
  4452.             return None
  4453.  
  4454.         faxtype = -1
  4455.         for line in stdout.split('\n'):
  4456.             if line.find('fax-type') == -1:
  4457.                 continue
  4458.             
  4459.             res = re.search('(\\d+)', line)
  4460.             if res:
  4461.                 resg = res.groups()
  4462.                 faxtype = resg[0]
  4463.             
  4464.             if faxtype >= 0:
  4465.                 break
  4466.                 continue
  4467.         
  4468.         if faxtype <= 0:
  4469.             return None
  4470.         if faxtype == 4:
  4471.             return 'MFG:HP;MDL:Fax 2;DES:HP Fax 2;'
  4472.         return 'MFG:HP;MDL:Fax;DES:HP Fax;'
  4473.  
  4474.     
  4475.     def get_hplip_uri_for_network_printer(self, host, mode):
  4476.         os.environ['HOST'] = host
  4477.         if mode == 'print':
  4478.             mod = '-c'
  4479.         elif mode == 'fax':
  4480.             mod = '-f'
  4481.         else:
  4482.             mod = '-c'
  4483.         cmd = 'hp-makeuri ' + mod + ' "${HOST}"'
  4484.         debugprint(host + ': ' + cmd)
  4485.         uri = None
  4486.         
  4487.         try:
  4488.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4489.             (stdout, stderr) = p.communicate()
  4490.             if p.returncode != 0:
  4491.                 return None
  4492.         except:
  4493.             return None
  4494.  
  4495.         uri = stdout.strip()
  4496.         return uri
  4497.  
  4498.     
  4499.     def getNetworkPrinterMakeModel(self, host = None, device = None):
  4500.         '''
  4501.         Try to determine the make and model for the currently selected
  4502.         network printer, and store this in the data structure for the
  4503.         printer.
  4504.         Returns (hostname or None, uri or None).
  4505.         '''
  4506.         uri = None
  4507.         if device == None:
  4508.             device = self.device
  4509.         
  4510.         if host == None:
  4511.             s = device.uri.find('://')
  4512.             if s != -1:
  4513.                 s += 3
  4514.                 e = device.uri[s:].find(':')
  4515.                 if e == -1:
  4516.                     e = device.uri[s:].find('/')
  4517.                 
  4518.                 if e == -1:
  4519.                     e = device.uri[s:].find('?')
  4520.                 
  4521.                 if e == -1:
  4522.                     e = len(device.uri)
  4523.                 
  4524.                 host = device.uri[s:s + e]
  4525.             
  4526.         
  4527.         if host:
  4528.             os.environ['HOST'] = host
  4529.             cmd = '/usr/lib/cups/backend/snmp "${HOST}"'
  4530.             debugprint(host + ': ' + cmd)
  4531.             stdout = None
  4532.             
  4533.             try:
  4534.                 p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4535.                 (stdout, stderr) = p.communicate()
  4536.                 if p.returncode != 0:
  4537.                     stdout = None
  4538.             except:
  4539.                 pass
  4540.  
  4541.             if stdout != None:
  4542.                 uri = re.sub('^\\s*\\S+\\s+', '', stdout)
  4543.                 uri = re.sub('\\s.*$', '', uri)
  4544.                 mm = re.sub('^\\s*\\S+\\s+\\S+\\s+"', '', stdout)
  4545.                 mm = re.sub('"\\s+.*$', '', mm)
  4546.                 if mm and mm != '':
  4547.                     device.make_and_model = mm
  4548.                 
  4549.             
  4550.         
  4551.         make_and_model = None
  4552.         if len(device.make_and_model) > 7:
  4553.             make_and_model = device.make_and_model
  4554.         elif len(device.info) > 7:
  4555.             make_and_model = device.info
  4556.             make_and_model = re.sub('\\s*(\\(|\\d+\\.\\d+\\.\\d+\\.\\d+).*$', '', make_and_model)
  4557.         
  4558.         if make_and_model and not (device.id):
  4559.             mk = None
  4560.             md = None
  4561.             (mk, md) = cupshelpers.ppds.ppdMakeModelSplit(make_and_model)
  4562.             device.id = 'MFG:' + mk + ';MDL:' + md + ';DES:' + mk + ' ' + md + ';'
  4563.             device.id_dict = cupshelpers.parseDeviceID(device.id)
  4564.             device.make_and_model = '%s %s' % (mk, md)
  4565.             device.info = device.make_and_model
  4566.         
  4567.         return (host, uri)
  4568.  
  4569.     
  4570.     def fillDeviceTab(self, current_uri = None):
  4571.         
  4572.         try:
  4573.             devices = self.fetchDevices()
  4574.         except cups.IPPError:
  4575.             (e, msg) = None
  4576.             self.show_IPP_Error(e, msg)
  4577.             devices = { }
  4578.         except:
  4579.             nonfatalException()
  4580.             devices = { }
  4581.  
  4582.         if current_uri:
  4583.             if devices.has_key(current_uri):
  4584.                 current = devices.pop(current_uri)
  4585.                 current.info += _(' (Current)')
  4586.             elif devices.has_key(current_uri.replace(':9100', '')):
  4587.                 current_uri = current_uri.replace(':9100', '')
  4588.                 current = devices.pop(current_uri)
  4589.                 current.info += _(' (Current)')
  4590.             else:
  4591.                 current = cupshelpers.Device(current_uri)
  4592.                 current.info = 'Current device'
  4593.         
  4594.         devices = devices.values()
  4595.         for device in devices:
  4596.             if device.type == 'socket':
  4597.                 device.uri = device.uri.replace(':9100', '')
  4598.                 continue
  4599.         
  4600.         
  4601.         def replace_generic(device):
  4602.             if device.uri == 'hp:/no_device_found':
  4603.                 device.uri = 'hp'
  4604.             elif device.uri == 'hpfax:/no_device_found':
  4605.                 device.uri = 'hpfax'
  4606.             
  4607.             return device
  4608.  
  4609.         devices = map(replace_generic, devices)
  4610.         for i in range(len(devices) - 1):
  4611.             for j in range(i + 1, len(devices)):
  4612.                 device1 = devices[i]
  4613.                 device2 = devices[j]
  4614.                 if device1.uri == 'delete' or device2.uri == 'delete':
  4615.                     continue
  4616.                 
  4617.                 if device1.uri == device2.uri:
  4618.                     if not device1.id:
  4619.                         device1.uri = 'delete'
  4620.                     elif not device2.id:
  4621.                         device2.uri = 'delete'
  4622.                     elif len(device1.id) < len(device2.id):
  4623.                         device1.uri = 'delete'
  4624.                     else:
  4625.                         device2.uri = 'delete'
  4626.                 device1.id
  4627.             
  4628.         
  4629.         devices = filter((lambda x: x.uri not in ('hp', 'hpfax', 'hal', 'beh', 'scsi', 'http', 'delete')), devices)
  4630.         self.devices = []
  4631.         for device in devices:
  4632.             physicaldevice = PhysicalDevice(device)
  4633.             
  4634.             try:
  4635.                 i = self.devices.index(physicaldevice)
  4636.                 self.devices[i].add_device(device)
  4637.             continue
  4638.             except ValueError:
  4639.                 self.devices.append(physicaldevice)
  4640.                 continue
  4641.             
  4642.  
  4643.         
  4644.         self.devices.sort()
  4645.         other = cupshelpers.Device('', **{
  4646.             'device-info': _('Other') })
  4647.         self.devices.append(PhysicalDevice(other))
  4648.         device_select_index = 0
  4649.         if current_uri:
  4650.             current_device = PhysicalDevice(current)
  4651.             
  4652.             try:
  4653.                 i = self.devices.index(current_device)
  4654.                 self.devices[i].add_device(current)
  4655.                 device_select_index = i
  4656.                 devs = self.devices[i].get_devices()
  4657.             except ValueError:
  4658.                 None<EXCEPTION MATCH>ValueError
  4659.                 None<EXCEPTION MATCH>ValueError
  4660.                 self.devices.insert(0, current_device)
  4661.             except:
  4662.                 None<EXCEPTION MATCH>ValueError<EXCEPTION MATCH>ValueError
  4663.             
  4664.  
  4665.         None<EXCEPTION MATCH>ValueError
  4666.         model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
  4667.         network_iter = model.append(None, row = [
  4668.             _('Network Printer'),
  4669.             None,
  4670.             False])
  4671.         network_dict = {
  4672.             'device-class': 'network',
  4673.             'device-info': _('Find Network Printer') }
  4674.         network = cupshelpers.Device('network', **network_dict)
  4675.         find_nw_iter = model.append(network_iter, row = [
  4676.             network_dict['device-info'],
  4677.             PhysicalDevice(network),
  4678.             False])
  4679.         model.insert_after(network_iter, find_nw_iter, row = [
  4680.             '',
  4681.             None,
  4682.             True])
  4683.         self.devices_find_nw_iter = find_nw_iter
  4684.         self.tvNPDevices.set_model(model)
  4685.         i = 0
  4686.         device_select_path = None
  4687.         for device in self.devices:
  4688.             devs = device.get_devices()
  4689.             network = devs[0].device_class == 'network'
  4690.             row = [
  4691.                 device.get_info(),
  4692.                 device,
  4693.                 False]
  4694.             if network:
  4695.                 if devs[0].uri != devs[0].type:
  4696.                     iter = model.insert_before(network_iter, find_nw_iter, row = row)
  4697.                     if device_select_index == i:
  4698.                         network_path = model.get_path(network_iter)
  4699.                         self.tvNPDevices.expand_row(network_path, False)
  4700.                     
  4701.                 else:
  4702.                     iter = model.append(network_iter, row = row)
  4703.             else:
  4704.                 iter = model.insert_before(None, network_iter, row = row)
  4705.             if device_select_index == i:
  4706.                 device_select_path = model.get_path(iter)
  4707.                 self.tvNPDevices.scroll_to_cell(device_select_path, row_align = 0.5)
  4708.                 column = self.tvNPDevices.get_column(0)
  4709.                 self.tvNPDevices.set_cursor(device_select_path, column)
  4710.             
  4711.             i += 1
  4712.         
  4713.         connection_select_path = 0
  4714.         if current_uri:
  4715.             model = self.tvNPDeviceURIs.get_model()
  4716.             iter = model.get_iter_first()
  4717.             i = 0
  4718.             while iter:
  4719.                 dev = model.get_value(iter, 1)
  4720.                 if current_uri == dev.uri:
  4721.                     connection_select_path = i
  4722.                     break
  4723.                 
  4724.                 iter = model.iter_next(iter)
  4725.                 i += 1
  4726.         
  4727.         column = self.tvNPDeviceURIs.get_column(0)
  4728.         self.tvNPDeviceURIs.set_cursor(connection_select_path, column)
  4729.  
  4730.     
  4731.     def on_entNPTDevice_changed(self, entry):
  4732.         self.setNPButtons()
  4733.  
  4734.     
  4735.     def browse_smb_hosts(self):
  4736.         '''Initialise the SMB tree store.'''
  4737.         store = self.smb_store
  4738.         store.clear()
  4739.         self.busy(self.SMBBrowseDialog)
  4740.         
  4741.         class X:
  4742.             pass
  4743.  
  4744.         dummy = X()
  4745.         dummy.smbc_type = pysmb.smbc.PRINTER_SHARE
  4746.         dummy.name = _('Scanning...')
  4747.         dummy.comment = ''
  4748.         store.append(None, [
  4749.             dummy])
  4750.         while gtk.events_pending():
  4751.             gtk.main_iteration()
  4752.         debug = 0
  4753.         if get_debugging():
  4754.             debug = 10
  4755.         
  4756.         smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4757.         ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4758.         entries = None
  4759.         
  4760.         try:
  4761.             while smbc_auth.perform_authentication() > 0:
  4762.                 
  4763.                 try:
  4764.                     entries = ctx.opendir('smb://').getdents()
  4765.                 continue
  4766.                 except Exception:
  4767.                     e = None
  4768.                     smbc_auth.failed(e)
  4769.                     continue
  4770.                 
  4771.  
  4772.                 None<EXCEPTION MATCH>Exception
  4773.         except RuntimeError:
  4774.             (e, s) = None
  4775.             if e != errno.ENOENT:
  4776.                 debugprint('Runtime error: %s' % repr((e, s)))
  4777.             
  4778.         except:
  4779.             e != errno.ENOENT
  4780.             nonfatalException()
  4781.  
  4782.         store.clear()
  4783.         if entries:
  4784.             for entry in entries:
  4785.                 if entry.smbc_type in [
  4786.                     pysmb.smbc.WORKGROUP,
  4787.                     pysmb.smbc.SERVER]:
  4788.                     iter = store.append(None, [
  4789.                         entry])
  4790.                     i = store.append(iter)
  4791.                     continue
  4792.             
  4793.         
  4794.         specified_uri = SMBURI(uri = self.entSMBURI.get_text())
  4795.         (group, host, share, user, password) = specified_uri.separate()
  4796.         if len(host) > 0:
  4797.             
  4798.             class FakeEntry:
  4799.                 pass
  4800.  
  4801.             toplevel = FakeEntry()
  4802.             toplevel.smbc_type = pysmb.smbc.SERVER
  4803.             toplevel.name = host
  4804.             toplevel.comment = ''
  4805.             iter = store.append(None, [
  4806.                 toplevel])
  4807.             i = store.append(iter)
  4808.             path = store.get_path(iter)
  4809.             self.tvSMBBrowser.expand_row(path, 0)
  4810.         
  4811.         self.ready(self.SMBBrowseDialog)
  4812.         if store.get_iter_first() == None:
  4813.             self.SMBBrowseDialog.hide()
  4814.             show_info_dialog(_('No Print Shares'), _('There were no print shares found.  Please check that the Samba service is marked as trusted in your firewall configuration.') + '\n\n' + TEXT_start_firewall_tool, parent = self.NewPrinterWindow)
  4815.         
  4816.  
  4817.     
  4818.     def smb_select_function(self, path):
  4819.         """Don't allow this path to be selected unless it is a leaf."""
  4820.         iter = self.smb_store.get_iter(path)
  4821.         return not self.smb_store.iter_has_child(iter)
  4822.  
  4823.     
  4824.     def smbbrowser_cell_share(self, column, cell, model, iter):
  4825.         entry = model.get_value(iter, 0)
  4826.         share = ''
  4827.         if entry != None:
  4828.             share = entry.name
  4829.         
  4830.         cell.set_property('text', share)
  4831.  
  4832.     
  4833.     def smbbrowser_cell_comment(self, column, cell, model, iter):
  4834.         entry = model.get_value(iter, 0)
  4835.         comment = ''
  4836.         if entry != None:
  4837.             comment = entry.comment
  4838.         
  4839.         cell.set_property('text', comment)
  4840.  
  4841.     
  4842.     def on_tvSMBBrowser_row_activated(self, view, path, column):
  4843.         '''Handle double-clicks in the SMB tree view.'''
  4844.         store = self.smb_store
  4845.         iter = store.get_iter(path)
  4846.         entry = store.get_value(iter, 0)
  4847.         if entry and entry.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4848.             self.btnSMBBrowseOk.clicked()
  4849.             return None
  4850.         if view.row_expanded(path):
  4851.             view.collapse_row(path)
  4852.         else:
  4853.             self.on_tvSMBBrowser_row_expanded(view, iter, path)
  4854.  
  4855.     
  4856.     def on_tvSMBBrowser_row_expanded(self, view, iter, path):
  4857.         '''Handler for expanding a row in the SMB tree view.'''
  4858.         model = view.get_model()
  4859.         entry = model.get_value(iter, 0)
  4860.         if entry == None:
  4861.             return None
  4862.         if entry.smbc_type == pysmb.smbc.WORKGROUP:
  4863.             
  4864.             try:
  4865.                 if self.expanding_row:
  4866.                     return None
  4867.             except:
  4868.                 entry == None
  4869.                 self.expanding_row = 1
  4870.  
  4871.             self.busy(self.SMBBrowseDialog)
  4872.             uri = 'smb://%s/' % entry.name
  4873.             debug = 0
  4874.             if get_debugging():
  4875.                 debug = 10
  4876.             
  4877.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4878.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4879.             entries = []
  4880.             
  4881.             try:
  4882.                 while smbc_auth.perform_authentication() > 0:
  4883.                     
  4884.                     try:
  4885.                         entries = ctx.opendir(uri).getdents()
  4886.                     continue
  4887.                     except Exception:
  4888.                         e = None
  4889.                         smbc_auth.failed(e)
  4890.                         continue
  4891.                     
  4892.  
  4893.                     None<EXCEPTION MATCH>Exception
  4894.             except RuntimeError:
  4895.                 (e, s) = None
  4896.                 if e != errno.ENOENT:
  4897.                     debugprint('Runtime error: %s' % repr((e, s)))
  4898.                 
  4899.             except:
  4900.                 e != errno.ENOENT
  4901.                 nonfatalException()
  4902.  
  4903.             while model.iter_has_child(iter):
  4904.                 i = model.iter_nth_child(iter, 0)
  4905.                 model.remove(i)
  4906.             for entry in entries:
  4907.                 if entry.smbc_type in [
  4908.                     pysmb.smbc.SERVER,
  4909.                     pysmb.smbc.PRINTER_SHARE]:
  4910.                     i = model.append(iter, [
  4911.                         entry])
  4912.                 
  4913.                 if entry.smbc_type == pysmb.smbc.SERVER:
  4914.                     n = model.append(i)
  4915.                     continue
  4916.             
  4917.             view.expand_row(path, 0)
  4918.             del self.expanding_row
  4919.             self.ready(self.SMBBrowseDialog)
  4920.         elif entry.smbc_type == pysmb.smbc.SERVER:
  4921.             
  4922.             try:
  4923.                 if self.expanding_row:
  4924.                     return None
  4925.             except:
  4926.                 entry == None
  4927.                 self.expanding_row = 1
  4928.  
  4929.             self.busy(self.SMBBrowseDialog)
  4930.             uri = 'smb://%s/' % entry.name
  4931.             debug = 0
  4932.             if get_debugging():
  4933.                 debug = 10
  4934.             
  4935.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4936.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4937.             shares = []
  4938.             
  4939.             try:
  4940.                 while smbc_auth.perform_authentication() > 0:
  4941.                     
  4942.                     try:
  4943.                         shares = ctx.opendir(uri).getdents()
  4944.                     continue
  4945.                     except Exception:
  4946.                         e = None
  4947.                         smbc_auth.failed(e)
  4948.                         continue
  4949.                     
  4950.  
  4951.                     None<EXCEPTION MATCH>Exception
  4952.             except RuntimeError:
  4953.                 (e, s) = None
  4954.                 if e != errno.EACCES and e != errno.EPERM:
  4955.                     debugprint('Runtime error: %s' % repr((e, s)))
  4956.                 
  4957.             except:
  4958.                 e != errno.EPERM
  4959.                 nonfatalException()
  4960.  
  4961.             while model.iter_has_child(iter):
  4962.                 i = model.iter_nth_child(iter, 0)
  4963.                 model.remove(i)
  4964.             for share in shares:
  4965.                 if share.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4966.                     i = model.append(iter, [
  4967.                         share])
  4968.                     debugprint(repr(share))
  4969.                     continue
  4970.             
  4971.             view.expand_row(path, 0)
  4972.             del self.expanding_row
  4973.             self.ready(self.SMBBrowseDialog)
  4974.         
  4975.  
  4976.     
  4977.     def on_entSMBURI_changed(self, ent):
  4978.         uri = ent.get_text()
  4979.         (group, host, share, user, password) = SMBURI(uri = uri).separate()
  4980.         if user:
  4981.             self.entSMBUsername.set_text(user)
  4982.         
  4983.         if password:
  4984.             self.entSMBPassword.set_text(password)
  4985.         
  4986.         if user or password:
  4987.             uri = SMBURI(group = group, host = host, share = share).get_uri()
  4988.             ent.set_text(uri)
  4989.             self.rbtnSMBAuthSet.set_active(True)
  4990.         elif self.entSMBUsername.get_text() == '':
  4991.             self.rbtnSMBAuthPrompt.set_active(True)
  4992.         
  4993.         self.btnSMBVerify.set_sensitive(bool(uri))
  4994.         self.setNPButtons()
  4995.  
  4996.     
  4997.     def on_tvSMBBrowser_cursor_changed(self, widget):
  4998.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  4999.         is_share = False
  5000.         if iter:
  5001.             entry = store.get_value(iter, 0)
  5002.             if entry:
  5003.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  5004.             
  5005.         
  5006.         if iter != None:
  5007.             pass
  5008.         self.btnSMBBrowseOk.set_sensitive(is_share)
  5009.  
  5010.     
  5011.     def on_btnSMBBrowse_clicked(self, button):
  5012.         self.btnSMBBrowseOk.set_sensitive(False)
  5013.         self.SMBBrowseDialog.show()
  5014.         self.browse_smb_hosts()
  5015.  
  5016.     
  5017.     def on_btnSMBBrowseOk_clicked(self, button):
  5018.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  5019.         is_share = False
  5020.         if iter:
  5021.             entry = store.get_value(iter, 0)
  5022.             if entry:
  5023.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  5024.             
  5025.         
  5026.         if not iter or not is_share:
  5027.             self.SMBBrowseDialog.hide()
  5028.             return None
  5029.         parent_iter = store.iter_parent(iter)
  5030.         domain_iter = store.iter_parent(parent_iter)
  5031.         share = store.get_value(iter, 0)
  5032.         host = store.get_value(parent_iter, 0)
  5033.         if domain_iter:
  5034.             group = store.get_value(domain_iter, 0).name
  5035.         else:
  5036.             group = ''
  5037.         uri = SMBURI(group = group, host = host.name, share = share.name).get_uri()
  5038.         self.entSMBUsername.set_text('')
  5039.         self.entSMBPassword.set_text('')
  5040.         self.entSMBURI.set_text(uri)
  5041.         self.SMBBrowseDialog.hide()
  5042.  
  5043.     
  5044.     def on_btnSMBBrowseCancel_clicked(self, widget, *args):
  5045.         self.SMBBrowseDialog.hide()
  5046.  
  5047.     
  5048.     def on_btnSMBBrowseRefresh_clicked(self, button):
  5049.         self.browse_smb_hosts()
  5050.  
  5051.     
  5052.     def on_rbtnSMBAuthSet_toggled(self, widget):
  5053.         self.tblSMBAuth.set_sensitive(widget.get_active())
  5054.  
  5055.     
  5056.     def on_btnSMBVerify_clicked(self, button):
  5057.         uri = self.entSMBURI.get_text()
  5058.         (group, host, share, u, p) = SMBURI(uri = uri).separate()
  5059.         user = ''
  5060.         passwd = ''
  5061.         reason = None
  5062.         auth_set = self.rbtnSMBAuthSet.get_active()
  5063.         if auth_set:
  5064.             user = self.entSMBUsername.get_text()
  5065.             passwd = self.entSMBPassword.get_text()
  5066.         
  5067.         accessible = False
  5068.         canceled = False
  5069.         self.busy()
  5070.         
  5071.         try:
  5072.             debug = 0
  5073.             if get_debugging():
  5074.                 debug = 10
  5075.             
  5076.             if auth_set:
  5077.                 
  5078.                 def do_auth(svr, shr, wg, un, pw):
  5079.                     return (group, user, passwd)
  5080.  
  5081.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = do_auth)
  5082.                 f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  5083.                 accessible = True
  5084.             else:
  5085.                 smbc_auth = pysmb.AuthContext(self.NewPrinterWindow, workgroup = group, user = user, passwd = passwd)
  5086.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  5087.                 while smbc_auth.perform_authentication() > 0:
  5088.                     
  5089.                     try:
  5090.                         f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  5091.                         accessible = True
  5092.                     continue
  5093.                     except Exception:
  5094.                         e = None
  5095.                         smbc_auth.failed(e)
  5096.                         continue
  5097.                     
  5098.  
  5099.                     None<EXCEPTION MATCH>Exception
  5100.                 if not accessible:
  5101.                     canceled = True
  5102.         except RuntimeError:
  5103.             (e, s) = None
  5104.             debugprint('Error accessing share: %s' % repr((e, s)))
  5105.             reason = s
  5106.         except:
  5107.             nonfatalException()
  5108.         
  5109.  
  5110.         self.ready()
  5111.         if accessible:
  5112.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  5113.             return None
  5114.  
  5115.     
  5116.     def update_IPP_URI_label(self):
  5117.         hostname = self.entNPTIPPHostname.get_text()
  5118.         queue = self.entNPTIPPQueuename.get_text()
  5119.         if len(hostname) > 0:
  5120.             pass
  5121.         valid = queue != '/printers/'
  5122.         if valid:
  5123.             uri = '%s://%s%s' % (self.device.type, hostname, queue)
  5124.             self.lblIPPURI.set_text(uri)
  5125.             self.lblIPPURI.show()
  5126.             self.entNPTIPPQueuename.show()
  5127.         else:
  5128.             self.lblIPPURI.hide()
  5129.         self.btnIPPVerify.set_sensitive(valid)
  5130.         self.setNPButtons()
  5131.  
  5132.     
  5133.     def on_entNPTIPPHostname_changed(self, ent):
  5134.         valid = len(ent.get_text()) > 0
  5135.         self.update_IPP_URI_label()
  5136.  
  5137.     
  5138.     def on_entNPTIPPQueuename_changed(self, ent):
  5139.         self.update_IPP_URI_label()
  5140.  
  5141.     
  5142.     def on_btnIPPVerify_clicked(self, button):
  5143.         uri = self.lblIPPURI.get_text()
  5144.         (scheme, rest) = urllib.splittype(uri)
  5145.         (hostport, rest) = urllib.splithost(rest)
  5146.         verified = False
  5147.         if hostport != None:
  5148.             (host, port) = urllib.splitnport(hostport, defport = 631)
  5149.             if uri.startswith('https:'):
  5150.                 encryption = cups.HTTP_ENCRYPT_ALWAYS
  5151.             else:
  5152.                 encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
  5153.             
  5154.             def get_attributes():
  5155.                 c = cups.Connection(host = host, port = port, encryption = encryption)
  5156.                 return c.getPrinterAttributes(uri = uri)
  5157.  
  5158.             op = TimedOperation(get_attributes)
  5159.             self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Verifying') + '</span>\n\n' + _('Verifying printer'))
  5160.             self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  5161.             self.WaitWindow.show()
  5162.             self.busy(self.WaitWindow)
  5163.             source = gobject.timeout_add(10000, op.cancel)
  5164.             
  5165.             try:
  5166.                 attributes = op.run()
  5167.                 verified = True
  5168.             except OperationCanceled:
  5169.                 (None, None, None, None)
  5170.                 (None, None, None, None)
  5171.             except cups.IPPError:
  5172.                 (e, msg) = None
  5173.                 debugprint('Failed to get attributes: %s (%d)' % (msg, e))
  5174.             except:
  5175.                 (None, None, None, None)
  5176.                 nonfatalException()
  5177.  
  5178.             gobject.source_remove(source)
  5179.             self.WaitWindow.hide()
  5180.         else:
  5181.             debugprint(uri)
  5182.         if verified:
  5183.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  5184.         else:
  5185.             show_error_dialog(_('Inaccessible'), _('This print share is not accessible.'), self.NewPrinterWindow)
  5186.  
  5187.     
  5188.     def on_expNPDeviceURIs_expanded(self, widget, UNUSED):
  5189.         parent = widget.get_parent()
  5190.         (expand, fill, padding, pack_type) = parent.query_child_packing(widget)
  5191.         expand = widget.get_expanded()
  5192.         parent.set_child_packing(widget, expand, fill, padding, pack_type)
  5193.  
  5194.     
  5195.     def device_row_separator_fn(self, model, iter):
  5196.         return model.get_value(iter, 2)
  5197.  
  5198.     
  5199.     def device_row_activated(self, view, path, column):
  5200.         if view.row_expanded(path):
  5201.             view.collapse_row(path)
  5202.         else:
  5203.             view.expand_row(path, False)
  5204.  
  5205.     
  5206.     def device_select_function(self, path):
  5207.         '''
  5208.         Allow this path to be selected as long as there
  5209.         is a device associated with it.  Otherwise, expand or collapse it.
  5210.         '''
  5211.         model = self.tvNPDevices.get_model()
  5212.         iter = model.get_iter(path)
  5213.         if model.get_value(iter, 1) != None:
  5214.             return True
  5215.         self.device_row_activated(self.tvNPDevices, path, None)
  5216.         return False
  5217.  
  5218.     
  5219.     def on_tvNPDevices_cursor_changed(self, widget):
  5220.         (path, column) = widget.get_cursor()
  5221.         if path == None:
  5222.             return None
  5223.         model = widget.get_model()
  5224.         iter = model.get_iter(path)
  5225.         physicaldevice = model.get_value(iter, 1)
  5226.         if physicaldevice == None:
  5227.             return None
  5228.         for device in physicaldevice.get_devices():
  5229.             if device.type == 'parallel':
  5230.                 device.menuentry = _('Parallel Port')
  5231.                 continue
  5232.             physicaldevice == None
  5233.             if device.type == 'serial':
  5234.                 device.menuentry = _('Serial Port')
  5235.                 continue
  5236.             path == None
  5237.             if device.type == 'usb':
  5238.                 device.menuentry = _('USB')
  5239.                 continue
  5240.             if device.type == 'bluetooth':
  5241.                 device.menuentry = _('Bluetooth')
  5242.                 continue
  5243.             if device.type == 'hp':
  5244.                 device.menuentry = _('HP Linux Imaging and Printing (HPLIP)')
  5245.                 continue
  5246.             if device.type == 'hpfax':
  5247.                 device.menuentry = _('Fax') + ' - ' + _('HP Linux Imaging and Printing (HPLIP)')
  5248.                 continue
  5249.             if device.type == 'hal':
  5250.                 device.menuentry = _('Hardware Abstraction Layer (HAL)')
  5251.                 continue
  5252.             None if device.type == 'socket' else queue != ''
  5253.             if device.type == 'smb':
  5254.                 device.menuentry = _('Windows Printer via SAMBA')
  5255.                 continue
  5256.             if device.type == 'ipp':
  5257.                 device.menuentry = _('IPP')
  5258.                 continue
  5259.             None if device.type == 'http' or device.type == 'https' else None if cupsqueue == 'cups' else protocol != None
  5260.             device.menuentry = device.uri
  5261.         
  5262.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5263.         self.tvNPDeviceURIs.set_model(model)
  5264.         if physicaldevice.get_data('checked-hplip') != True:
  5265.             hp_drivable = False
  5266.             is_network = False
  5267.             remotecups = False
  5268.             host = None
  5269.             device_dict = {
  5270.                 'device-class': 'network' }
  5271.             if physicaldevice._network_host:
  5272.                 host = physicaldevice._network_host
  5273.             
  5274.             for device in physicaldevice.get_devices():
  5275.                 None if device.type == 'hp' else host
  5276.             
  5277.             if not hp_drivable and is_network and not remotecups:
  5278.                 hplipuri = self.get_hplip_uri_for_network_printer(host, 'print')
  5279.                 if hplipuri:
  5280.                     dev = cupshelpers.Device(hplipuri, **device_dict)
  5281.                     dev.menuentry = 'HP Linux Imaging and Printing (HPLIP)'
  5282.                     physicaldevice.add_device(dev)
  5283.                     faxuri = self.get_hplip_uri_for_network_printer(host, 'fax')
  5284.                     if faxuri:
  5285.                         faxdevid = self.get_hpfax_device_id(faxuri)
  5286.                         device_dict['device-id'] = faxdevid
  5287.                         device_dict['device-info'] = _('Fax')
  5288.                         faxdev = cupshelpers.Device(faxuri, **device_dict)
  5289.                         faxdev.menuentry = _('Fax') + ' - ' + 'HP Linux Imaging and Printing (HPLIP)'
  5290.                         physicaldevice.add_device(faxdev)
  5291.                     
  5292.                 
  5293.                 physicaldevice.set_data('checked-hplip', True)
  5294.             
  5295.         
  5296.         n = 0
  5297.         for device in physicaldevice.get_devices():
  5298.             model.append((device.menuentry, device))
  5299.             n += 1
  5300.         
  5301.         column = self.tvNPDeviceURIs.get_column(0)
  5302.         self.tvNPDeviceURIs.set_cursor(0, column)
  5303.         if n > 1:
  5304.             self.expNPDeviceURIs.show_all()
  5305.         else:
  5306.             self.expNPDeviceURIs.hide()
  5307.  
  5308.     
  5309.     def on_tvNPDeviceURIs_cursor_changed(self, widget):
  5310.         (path, column) = widget.get_cursor()
  5311.         if path == None:
  5312.             return None
  5313.         model = widget.get_model()
  5314.         iter = model.get_iter(path)
  5315.         device = model.get_value(iter, 1)
  5316.         self.device = device
  5317.         self.lblNPDeviceDescription.set_text('')
  5318.         page = self.new_printer_device_tabs.get(device.type, 1)
  5319.         self.ntbkNPType.set_current_page(page)
  5320.         location = ''
  5321.         type = device.type
  5322.         url = device.uri.split(':', 1)[-1]
  5323.         if page == 0:
  5324.             if device.type == 'parallel':
  5325.                 text = _('A printer connected to the parallel port.')
  5326.             elif device.type == 'usb':
  5327.                 text = _('A printer connected to a USB port.')
  5328.             elif device.type == 'bluetooth':
  5329.                 text = _('A printer connected via Bluetooth.')
  5330.             elif device.type == 'hp':
  5331.                 text = _('HPLIP software driving a printer, or the printer function of a multi-function device.')
  5332.             elif device.type == 'hpfax':
  5333.                 text = _('HPLIP software driving a fax machine, or the fax function of a multi-function device.')
  5334.             elif device.type == 'hal':
  5335.                 text = _('Local printer detected by the Hardware Abstraction Layer (HAL).')
  5336.             elif device.type == 'dnssd' or device.type == 'mdns':
  5337.                 (scheme, rest) = urllib.splittype(device.uri)
  5338.                 (name, rest) = urllib.splithost(rest)
  5339.                 (cupsqueue, rest) = urllib.splitquery(rest)
  5340.                 if cupsqueue[0] == '/':
  5341.                     cupsqueue = cupsqueue[1:]
  5342.                 
  5343.                 if cupsqueue == 'cups':
  5344.                     text = _('Remote CUPS printer via DNS-SD')
  5345.                 else:
  5346.                     protocol = None
  5347.                     if name.find('._ipp') != -1:
  5348.                         protocol = 'IPP'
  5349.                     elif name.find('._printer') != -1:
  5350.                         protocol = 'LPD'
  5351.                     elif name.find('._pdl-datastream') != -1:
  5352.                         protocol = 'AppSocket/JetDirect'
  5353.                     
  5354.                     if protocol != None:
  5355.                         text = _('%s network printer via DNS-SD') % protocol
  5356.                     else:
  5357.                         text = _('Network printer via DNS-SD')
  5358.             else:
  5359.                 text = device.uri
  5360.             self.lblNPDeviceDescription.set_text(text)
  5361.         elif device.type == 'socket':
  5362.             (scheme, rest) = urllib.splittype(device.uri)
  5363.             host = ''
  5364.             port = 9100
  5365.             if scheme == 'socket':
  5366.                 (hostport, rest) = urllib.splithost(rest)
  5367.                 (host, port) = urllib.splitnport(hostport, defport = port)
  5368.                 debugprint('socket: host is %s, port is %s' % (host, repr(port)))
  5369.                 location = host
  5370.             
  5371.             self.entNPTDirectJetHostname.set_text(host)
  5372.             self.entNPTDirectJetPort.set_text(str(port))
  5373.         elif device.type == 'serial':
  5374.             if not device.is_class:
  5375.                 options = device.uri.split('?')[1]
  5376.                 options = options.split('+')
  5377.                 option_dict = { }
  5378.                 for option in options:
  5379.                     (name, value) = option.split('=')
  5380.                     option_dict[name] = value
  5381.                 
  5382.                 for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', [
  5383.                     'none',
  5384.                     'odd',
  5385.                     'even']), (self.cmbNPTSerialFlow, 'flow', [
  5386.                     'none',
  5387.                     'soft',
  5388.                     'hard',
  5389.                     'hard'])):
  5390.                     if option_dict.has_key(name):
  5391.                         if optionvalues is None:
  5392.                             model = widget.get_model()
  5393.                             iter = model.get_iter_first()
  5394.                             nr = 0
  5395.                             while iter:
  5396.                                 value = model.get(iter, 0)[0]
  5397.                                 if value == option_dict[name]:
  5398.                                     widget.set_active(nr)
  5399.                                     break
  5400.                                 
  5401.                                 iter = model.iter_next(iter)
  5402.                                 nr += 1
  5403.                         else:
  5404.                             nr = optionvalues.index(option_dict[name])
  5405.                             widget.set_active(nr + 1)
  5406.                     optionvalues is None
  5407.                     widget.set_active(0)
  5408.                 
  5409.             
  5410.         elif device.type in ('ipp', 'http', 'https'):
  5411.             if device.uri.find(':') != -1:
  5412.                 match = re.match('(ipp|https?)://([^/]+)(.*)', device.uri)
  5413.                 if match:
  5414.                     server = match.group(2)
  5415.                     printer = match.group(3)
  5416.                 else:
  5417.                     server = ''
  5418.                     printer = ''
  5419.                 self.entNPTIPPHostname.set_text(server)
  5420.                 self.entNPTIPPQueuename.set_text(printer)
  5421.                 self.lblIPPURI.set_text(device.uri)
  5422.                 self.lblIPPURI.show()
  5423.                 self.entNPTIPPQueuename.show()
  5424.                 location = server
  5425.             else:
  5426.                 self.entNPTIPPHostname.set_text('')
  5427.                 self.entNPTIPPQueuename.set_text('/printers/')
  5428.                 self.entNPTIPPQueuename.show()
  5429.                 self.lblIPPURI.hide()
  5430.         elif device.type == 'lpd':
  5431.             self.cmbentNPTLpdHost.child.set_text('')
  5432.             self.cmbentNPTLpdQueue.child.set_text('')
  5433.             self.cmbentNPTLpdQueue.get_model().clear()
  5434.             self.btnNPTLpdProbe.set_sensitive(False)
  5435.             if len(device.uri) > 6:
  5436.                 host = device.uri[6:]
  5437.                 i = host.find('/')
  5438.                 if i != -1:
  5439.                     printer = host[i + 1:]
  5440.                     host = host[:i]
  5441.                 else:
  5442.                     printer = ''
  5443.                 self.cmbentNPTLpdHost.child.set_text(host)
  5444.                 self.cmbentNPTLpdQueue.child.set_text(printer)
  5445.                 location = host
  5446.                 self.btnNPTLpdProbe.set_sensitive(True)
  5447.             
  5448.         elif device.uri == 'smb':
  5449.             self.entSMBURI.set_text('')
  5450.             self.btnSMBVerify.set_sensitive(False)
  5451.         elif device.type == 'smb':
  5452.             self.entSMBUsername.set_text('')
  5453.             self.entSMBPassword.set_text('')
  5454.             self.entSMBURI.set_text(device.uri[6:])
  5455.             self.btnSMBVerify.set_sensitive(True)
  5456.         else:
  5457.             self.entNPTDevice.set_text(device.uri)
  5458.         
  5459.         try:
  5460.             if len(location) == 0 and self.device.device_class == 'direct':
  5461.                 if self.mainapp.connect_server == 'localhost' or self.mainapp.connect_server[0] == '/':
  5462.                     u = os.uname()
  5463.                     location = u[1]
  5464.                 else:
  5465.                     location = self.mainapp.connect_server
  5466.             
  5467.             self.entNPLocation.set_text(location)
  5468.         except:
  5469.             nonfatalException()
  5470.  
  5471.         self.setNPButtons()
  5472.  
  5473.     
  5474.     def on_cmbentNPTLpdHost_changed(self, cmbent):
  5475.         hostname = cmbent.get_active_text()
  5476.         self.btnNPTLpdProbe.set_sensitive(len(hostname) > 0)
  5477.         self.setNPButtons()
  5478.  
  5479.     
  5480.     def on_btnNPTLpdProbe_clicked(self, button):
  5481.         hostname = self.cmbentNPTLpdHost.get_active_text()
  5482.         server = probe_printer.LpdServer(hostname)
  5483.         self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for printers'))
  5484.         self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  5485.         self.WaitWindow.show_now()
  5486.         self.busy(self.WaitWindow)
  5487.         printers = server.probe()
  5488.         self.WaitWindow.hide()
  5489.         model = self.cmbentNPTLpdQueue.get_model()
  5490.         model.clear()
  5491.         for printer in printers:
  5492.             self.cmbentNPTLpdQueue.append_text(printer)
  5493.         
  5494.         if printers:
  5495.             self.cmbentNPTLpdQueue.set_active(0)
  5496.         
  5497.  
  5498.     
  5499.     def on_entNPTNetworkHostname_changed(self, ent):
  5500.         s = ent.get_text()
  5501.         self.btnNetworkFind.set_sensitive(len(s) > 0)
  5502.         self.lblNetworkFindNotFound.hide()
  5503.         self.setNPButtons()
  5504.  
  5505.     
  5506.     def on_btnNetworkFind_clicked(self, button):
  5507.         host = self.entNPTNetworkHostname.get_text()
  5508.         
  5509.         def found_callback(new_device):
  5510.             glib.idle_add(self.found_network_printer_callback, new_device)
  5511.  
  5512.         self.btnNetworkFind.set_sensitive(False)
  5513.         self.entNPTNetworkHostname.set_sensitive(False)
  5514.         self.network_found = 0
  5515.         self.lblNetworkFindSearching.show_all()
  5516.         finder = probe_printer.PrinterFinder()
  5517.         self.imgProcessWorking.show()
  5518.         self.spinner.start()
  5519.         finder.find(host, found_callback)
  5520.  
  5521.     
  5522.     def found_network_printer_callback(self, new_device):
  5523.         if new_device:
  5524.             self.network_found += 1
  5525.             dev = PhysicalDevice(new_device)
  5526.             
  5527.             try:
  5528.                 i = self.devices.index(dev)
  5529.                 self.devices[i].add_device(new_device)
  5530.                 (path, column) = self.tvNPDevices.get_cursor()
  5531.                 model = self.tvNPDevices.get_model()
  5532.                 iter = model.get_iter(path)
  5533.                 if model.get_value(iter, 1) == self.devices[i]:
  5534.                     self.on_tvNPDevices_cursor_changed(self.tvNPDevices)
  5535.             except ValueError:
  5536.                 self
  5537.                 self
  5538.                 dev.set_data('checked-hplip', True)
  5539.                 self.devices.append(dev)
  5540.                 self.devices.sort()
  5541.                 model = self.tvNPDevices.get_model()
  5542.                 iter = model.insert_before(None, self.devices_find_nw_iter, row = [
  5543.                     dev.get_info(),
  5544.                     dev,
  5545.                     False])
  5546.             except:
  5547.                 self
  5548.  
  5549.             if self.network_found == 1:
  5550.                 path = model.get_path(iter)
  5551.                 self.tvNPDevices.set_cursor(path)
  5552.             
  5553.         else:
  5554.             self.imgProcessWorking.hide()
  5555.             self.spinner.stop()
  5556.             self.lblNetworkFindSearching.hide()
  5557.             self.entNPTNetworkHostname.set_sensitive(True)
  5558.             self.btnNetworkFind.set_sensitive(True)
  5559.             if self.network_found == 0:
  5560.                 self.lblNetworkFindNotFound.set_markup('<i>' + _('No printer was found at that address.') + '</i>')
  5561.                 self.lblNetworkFindNotFound.show()
  5562.             
  5563.  
  5564.     
  5565.     def getDeviceURI(self):
  5566.         type = self.device.type
  5567.         page = self.new_printer_device_tabs.get(type, 1)
  5568.         device = type
  5569.         if page == 0:
  5570.             device = self.device.uri
  5571.         elif type == 'socket':
  5572.             host = self.entNPTDirectJetHostname.get_text()
  5573.             port = self.entNPTDirectJetPort.get_text()
  5574.             if host:
  5575.                 device += '://' + host
  5576.                 if port:
  5577.                     device += ':' + port
  5578.                 
  5579.             
  5580.         elif type in ('ipp', 'http', 'https'):
  5581.             if self.lblIPPURI.get_property('visible'):
  5582.                 device = self.lblIPPURI.get_text()
  5583.             
  5584.         elif type == 'lpd':
  5585.             host = self.cmbentNPTLpdHost.get_active_text()
  5586.             printer = self.cmbentNPTLpdQueue.get_active_text()
  5587.             if host:
  5588.                 device += '://' + host
  5589.                 if printer:
  5590.                     device += '/' + printer
  5591.                 
  5592.             
  5593.         elif type == 'serial':
  5594.             options = []
  5595.             for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', ('none', 'odd', 'even')), (self.cmbNPTSerialFlow, 'flow', ('none', 'soft', 'hard', 'hard'))):
  5596.                 nr = widget.get_active()
  5597.                 if nr:
  5598.                     if optionvalues is not None:
  5599.                         option = optionvalues[nr - 1]
  5600.                     else:
  5601.                         option = widget.get_active_text()
  5602.                     options.append(name + '=' + option)
  5603.                     continue
  5604.             
  5605.             options = '+'.join(options)
  5606.             device = self.device.uri.split('?')[0]
  5607.             if options:
  5608.                 device = device + '?' + options
  5609.             
  5610.         elif type == 'smb':
  5611.             uri = self.entSMBURI.get_text()
  5612.             (group, host, share, u, p) = SMBURI(uri = uri).separate()
  5613.             user = ''
  5614.             password = ''
  5615.             if self.rbtnSMBAuthSet.get_active():
  5616.                 user = self.entSMBUsername.get_text()
  5617.                 password = self.entSMBPassword.get_text()
  5618.             
  5619.             uri = SMBURI(group = group, host = host, share = share, user = user, password = password).get_uri()
  5620.             if uri:
  5621.                 device += '://' + uri
  5622.             
  5623.         else:
  5624.             device = self.entNPTDevice.get_text()
  5625.         return device
  5626.  
  5627.     
  5628.     def on_rbtnNPFoomatic_toggled(self, widget):
  5629.         rbtn1 = self.rbtnNPFoomatic.get_active()
  5630.         rbtn2 = self.rbtnNPPPD.get_active()
  5631.         rbtn3 = self.rbtnNPDownloadableDriverSearch.get_active()
  5632.         self.tvNPMakes.set_sensitive(rbtn1)
  5633.         self.filechooserPPD.set_sensitive(rbtn2)
  5634.         if rbtn1:
  5635.             page = 0
  5636.         
  5637.         if rbtn2:
  5638.             page = 1
  5639.         
  5640.         if rbtn3:
  5641.             page = 2
  5642.         
  5643.         self.ntbkPPDSource.set_current_page(page)
  5644.         if not rbtn3 and self.openprinting_query_handle:
  5645.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5646.             self.openprinting_query_handle = None
  5647.             self.btnNPDownloadableDriverSearch_label.set_text(_('Search'))
  5648.             model = gtk.ListStore(str, str)
  5649.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5650.             combobox.set_model(model)
  5651.             combobox.set_sensitive(False)
  5652.         
  5653.         for widget in [
  5654.             self.entNPDownloadableDriverSearch,
  5655.             self.cmbNPDownloadableDriverFoundPrinters]:
  5656.             widget.set_sensitive(rbtn3)
  5657.         
  5658.         if rbtn3:
  5659.             pass
  5660.         self.btnNPDownloadableDriverSearch.set_sensitive(self.openprinting_query_handle == None)
  5661.         self.setNPButtons()
  5662.  
  5663.     
  5664.     def on_filechooserPPD_selection_changed(self, widget):
  5665.         self.setNPButtons()
  5666.  
  5667.     
  5668.     def on_btnNPDownloadableDriverSearch_clicked(self, widget):
  5669.         if self.openprinting_query_handle != None:
  5670.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5671.             self.openprinting_query_handle = None
  5672.         
  5673.         widget.set_sensitive(False)
  5674.         label = self.btnNPDownloadableDriverSearch_label
  5675.         label.set_text(_('Searching'))
  5676.         searchterm = self.entNPDownloadableDriverSearch.get_text()
  5677.         self.openprinting_query_handle = self.openprinting.searchPrinters(searchterm, self.openprinting_printers_found)
  5678.         self.cmbNPDownloadableDriverFoundPrinters.set_sensitive(False)
  5679.  
  5680.     
  5681.     def openprinting_printers_found(self, status, user_data, printers):
  5682.         self.openprinting_query_handle = None
  5683.         button = self.btnNPDownloadableDriverSearch
  5684.         label = self.btnNPDownloadableDriverSearch_label
  5685.         gtk.gdk.threads_enter()
  5686.         
  5687.         try:
  5688.             label.set_text(_('Search'))
  5689.             button.set_sensitive(True)
  5690.             if status != 0:
  5691.                 print printers
  5692.                 print traceback.extract_tb(printers[2], limit = None)
  5693.                 gtk.gdk.threads_leave()
  5694.                 return None
  5695.             model = gtk.ListStore(str, str)
  5696.             sorted_list = []
  5697.             for id, name in printers.iteritems():
  5698.                 sorted_list.append((id, name))
  5699.             
  5700.             sorted_list.sort((lambda x, y: cups.modelSort(x[1], y[1])))
  5701.             sought = self.entNPDownloadableDriverSearch.get_text().lower()
  5702.             select_index = 0
  5703.             for id, name in sorted_list:
  5704.                 iter = model.append(None)
  5705.                 model.set_value(iter, 0, name)
  5706.                 model.set_value(iter, 1, id)
  5707.                 if name.lower() == sought:
  5708.                     select_index = model.get_path(iter)[0]
  5709.                     continue
  5710.                 None if len(printers) != 1 else status != 0
  5711.             
  5712.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5713.             combobox.set_model(model)
  5714.             combobox.set_active(select_index)
  5715.             combobox.set_sensitive(True)
  5716.             self.setNPButtons()
  5717.         except:
  5718.             nonfatalException()
  5719.  
  5720.         gtk.gdk.threads_leave()
  5721.  
  5722.     
  5723.     def on_cmbNPDownloadableDriverFoundPrinters_changed(self, widget):
  5724.         self.setNPButtons()
  5725.         if self.openprinting_query_handle != None:
  5726.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5727.             self.openprinting_query_handle = None
  5728.             self.drivers_lock.release()
  5729.         
  5730.         model = widget.get_model()
  5731.         iter = widget.get_active_iter()
  5732.         if iter:
  5733.             id = model.get_value(iter, 1)
  5734.         else:
  5735.             id = None
  5736.         if id == None:
  5737.             return None
  5738.         debugprint('Query drivers for %s' % id)
  5739.         self.drivers_lock.acquire(0)
  5740.         extra_options = dict()
  5741.         if self.DOWNLOADABLE_ONLYPPD:
  5742.             extra_options['onlyppdfiles'] = '1'
  5743.         
  5744.         self.openprinting_query_handle = self.openprinting.listDrivers(id, self.openprinting_drivers_found, extra_options = extra_options)
  5745.  
  5746.     
  5747.     def openprinting_drivers_found(self, status, user_data, drivers):
  5748.         if status != 0:
  5749.             print drivers
  5750.             print traceback.extract_tb(drivers[2], limit = None)
  5751.             return None
  5752.         self.openprinting_query_handle = None
  5753.         self.downloadable_drivers = drivers
  5754.         debugprint('Drivers query completed: %s' % drivers.keys())
  5755.         self.drivers_lock.release()
  5756.  
  5757.     
  5758.     def fillDownloadableDrivers(self):
  5759.         self.lblNPDownloadableDriverSupplier.set_text('')
  5760.         self.lblNPDownloadableDriverLicense.set_text('')
  5761.         self.lblNPDownloadableDriverDescription.set_text('')
  5762.         self.lblNPDownloadableDriverSupportContacts.set_text('')
  5763.         self.rbtnNPDownloadLicenseNo.set_active(True)
  5764.         self.frmNPDownloadableDriverLicenseTerms.hide()
  5765.         drivers = self.downloadable_drivers
  5766.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5767.         recommended_iter = None
  5768.         first_iter = None
  5769.         for driver in drivers.values():
  5770.             iter = model.append(None)
  5771.             if first_iter == None:
  5772.                 first_iter = iter
  5773.             
  5774.             model.set_value(iter, 0, driver['name'])
  5775.             model.set_value(iter, 1, driver)
  5776.             if driver['recommended']:
  5777.                 recommended_iter = iter
  5778.                 continue
  5779.         
  5780.         if recommended_iter == None:
  5781.             recommended_iter = first_iter
  5782.         
  5783.         treeview = self.tvNPDownloadableDrivers
  5784.         treeview.set_model(model)
  5785.         if recommended_iter != None:
  5786.             treeview.get_selection().select_iter(recommended_iter)
  5787.         
  5788.  
  5789.     
  5790.     def on_rbtnNPDownloadLicense_toggled(self, widget):
  5791.         self.setNPButtons()
  5792.  
  5793.     
  5794.     def fillMakeList(self):
  5795.         makes = self.ppds.getMakes()
  5796.         model = self.tvNPMakes.get_model()
  5797.         model.clear()
  5798.         found = False
  5799.         auto_make_lower = self.auto_make.lower()
  5800.         for make in makes:
  5801.             iter = model.append((make,))
  5802.             if make.lower() == auto_make_lower:
  5803.                 path = model.get_path(iter)
  5804.                 self.tvNPMakes.set_cursor(path)
  5805.                 self.tvNPMakes.scroll_to_cell(path, None, True, 0.5, 0.5)
  5806.                 found = True
  5807.                 continue
  5808.         
  5809.         if not found:
  5810.             self.tvNPMakes.set_cursor(0)
  5811.             self.tvNPMakes.scroll_to_cell(0, None, True, 0, 0)
  5812.         
  5813.         search = ''
  5814.         if self.device and self.device.id_dict:
  5815.             devid_dict = self.device.id_dict
  5816.             if devid_dict['MFG'] and devid_dict['MDL']:
  5817.                 search = devid_dict['MFG'] + ' ' + devid_dict['MDL']
  5818.             elif devid_dict['DES']:
  5819.                 search = devid_dict['DES']
  5820.             elif devid_dict['MFG']:
  5821.                 search = devid_dict['MFG']
  5822.             
  5823.         
  5824.         if search == '' and self.auto_make != None:
  5825.             search += self.auto_make
  5826.             if self.auto_model != None:
  5827.                 search += ' ' + self.auto_model
  5828.             
  5829.         
  5830.         self.entNPDownloadableDriverSearch.set_text(search)
  5831.  
  5832.     
  5833.     def on_tvNPMakes_cursor_changed(self, tvNPMakes):
  5834.         (path, column) = tvNPMakes.get_cursor()
  5835.         if path != None:
  5836.             model = tvNPMakes.get_model()
  5837.             iter = model.get_iter(path)
  5838.             self.NPMake = model.get(iter, 0)[0]
  5839.             self.fillModelList()
  5840.         
  5841.  
  5842.     
  5843.     def fillModelList(self):
  5844.         models = self.ppds.getModels(self.NPMake)
  5845.         model = self.tvNPModels.get_model()
  5846.         model.clear()
  5847.         selected = False
  5848.         is_auto_make = self.NPMake.lower() == self.auto_make.lower()
  5849.         if is_auto_make:
  5850.             auto_model_lower = self.auto_model.lower()
  5851.         
  5852.         for pmodel in models:
  5853.             iter = model.append((pmodel,))
  5854.             if is_auto_make and pmodel.lower() == auto_model_lower:
  5855.                 path = model.get_path(iter)
  5856.                 self.tvNPModels.set_cursor(path)
  5857.                 self.tvNPModels.scroll_to_cell(path, None, True, 0.5, 0.5)
  5858.                 selected = True
  5859.                 continue
  5860.         
  5861.         if not selected:
  5862.             self.tvNPModels.set_cursor(0)
  5863.             self.tvNPModels.scroll_to_cell(0, None, True, 0, 0)
  5864.         
  5865.         self.tvNPModels.columns_autosize()
  5866.  
  5867.     
  5868.     def fillDriverList(self, pmake, pmodel):
  5869.         self.NPModel = pmodel
  5870.         model = self.tvNPDrivers.get_model()
  5871.         model.clear()
  5872.         ppds = self.ppds.getInfoFromModel(pmake, pmodel)
  5873.         self.NPDrivers = self.ppds.orderPPDNamesByPreference(ppds.keys(), self.jockey_installed_files)
  5874.         for i in range(len(self.NPDrivers)):
  5875.             ppd = ppds[self.NPDrivers[i]]
  5876.             driver = ppd['ppd-make-and-model']
  5877.             driver = driver.replace(' (recommended)', '')
  5878.             
  5879.             try:
  5880.                 lpostfix = ' [%s]' % ppd['ppd-natural-language']
  5881.                 driver += lpostfix
  5882.             except KeyError:
  5883.                 pass
  5884.  
  5885.             if i == 0:
  5886.                 iter = model.append((driver + _(' (recommended)'),))
  5887.                 path = model.get_path(iter)
  5888.                 self.tvNPDrivers.get_selection().select_path(path)
  5889.                 self.tvNPDrivers.scroll_to_cell(path, None, True, 0.5, 0)
  5890.                 continue
  5891.             model.append((driver,))
  5892.         
  5893.         self.tvNPDrivers.columns_autosize()
  5894.  
  5895.     
  5896.     def on_NPDrivers_query_tooltip(self, tv, x, y, keyboard_mode, tooltip):
  5897.         drivername = self.NPDrivers[path[0]]
  5898.         ppddict = self.ppds.getInfoFromPPDName(drivername)
  5899.         markup = ppddict['ppd-make-and-model']
  5900.         if drivername.startswith('foomatic:'):
  5901.             markup += ' '
  5902.             markup += _('This PPD is generated by foomatic.')
  5903.         
  5904.         tooltip.set_markup(markup)
  5905.         return True
  5906.  
  5907.     
  5908.     def on_tvNPModels_cursor_changed(self, widget):
  5909.         (path, column) = widget.get_cursor()
  5910.         if path != None:
  5911.             model = widget.get_model()
  5912.             iter = model.get_iter(path)
  5913.             pmodel = model.get(iter, 0)[0]
  5914.             self.fillDriverList(self.NPMake, pmodel)
  5915.             self.on_tvNPDrivers_cursor_changed(self.tvNPDrivers)
  5916.         
  5917.  
  5918.     
  5919.     def on_tvNPDrivers_cursor_changed(self, widget):
  5920.         self.setNPButtons()
  5921.  
  5922.     
  5923.     def on_tvNPDownloadableDrivers_cursor_changed(self, widget):
  5924.         (model, iter) = widget.get_selection().get_selected()
  5925.         if not iter:
  5926.             (path, column) = widget.get_cursor()
  5927.             iter = model.get_iter(path)
  5928.         
  5929.         driver = model.get_value(iter, 1)
  5930.         import pprint as pprint
  5931.         pprint.pprint(driver)
  5932.         self.ntbkNPDownloadableDriverProperties.set_current_page(1)
  5933.         supplier = driver.get('supplier', _('OpenPrinting'))
  5934.         vendor = self.cbNPDownloadableDriverSupplierVendor
  5935.         active = driver['manufacturersupplied']
  5936.         
  5937.         def set_protect_active(widget, active):
  5938.             widget.set_active(active)
  5939.             widget.set_data('protect_active', active)
  5940.  
  5941.         set_protect_active(vendor, active)
  5942.         self.lblNPDownloadableDriverSupplier.set_text(supplier)
  5943.         license = driver.get('license', _('Distributable'))
  5944.         patents = self.cbNPDownloadableDriverLicensePatents
  5945.         free = self.cbNPDownloadableDriverLicenseFree
  5946.         set_protect_active(patents, driver['patents'])
  5947.         set_protect_active(free, driver['freesoftware'])
  5948.         self.lblNPDownloadableDriverLicense.set_text(license)
  5949.         description = driver.get('shortdescription', _('None'))
  5950.         self.lblNPDownloadableDriverDescription.set_markup(description)
  5951.         functionality = driver['functionality']
  5952.         for field in [
  5953.             'Graphics',
  5954.             'LineArt',
  5955.             'Photo',
  5956.             'Text']:
  5957.             key = field.lower()
  5958.             value = None
  5959.             hs = self.__dict__.get('hsDownloadableDriverPerf%s' % field)
  5960.             unknown = self.__dict__.get('lblDownloadableDriverPerf%sUnknown' % field)
  5961.             if functionality.has_key(key):
  5962.                 if hs:
  5963.                     
  5964.                     try:
  5965.                         value = int(functionality[key])
  5966.                         hs.set_value(value)
  5967.                         hs.show_all()
  5968.                         unknown.hide()
  5969.  
  5970.                 
  5971.             
  5972.             if value == None:
  5973.                 hs.hide()
  5974.                 unknown.show_all()
  5975.                 continue
  5976.         
  5977.         supportcontacts = ''
  5978.         if driver.has_key('supportcontacts'):
  5979.             for supportentry in driver['supportcontacts']:
  5980.                 if supportentry['name']:
  5981.                     supportcontact = ' - ' + supportentry['name']
  5982.                     supportcontact_extra = ''
  5983.                     if supportentry['url']:
  5984.                         supportcontact_extra = supportcontact_extra + supportentry['url']
  5985.                     
  5986.                     if supportentry['level']:
  5987.                         if supportcontact_extra:
  5988.                             supportcontact_extra = supportcontact_extra + _(', ')
  5989.                         
  5990.                         supportcontact_extra = supportcontact_extra + supportentry['level']
  5991.                     
  5992.                     if supportcontact_extra:
  5993.                         supportcontact = supportcontact + _('\n(%s)') % supportcontact_extra
  5994.                         if supportcontacts:
  5995.                             supportcontacts = supportcontacts + '\n'
  5996.                         
  5997.                         supportcontacts = supportcontacts + supportcontact
  5998.                     
  5999.                 supportcontact_extra
  6000.             
  6001.         
  6002.         if not supportcontacts:
  6003.             supportcontacts = _('No support contacts known')
  6004.         
  6005.         self.lblNPDownloadableDriverSupportContacts.set_text(supportcontacts)
  6006.         if driver.has_key('licensetext'):
  6007.             self.frmNPDownloadableDriverLicenseTerms.show()
  6008.             terms = driver.get('licensetext', _('Not specified.'))
  6009.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  6010.         else:
  6011.             self.frmNPDownloadableDriverLicenseTerms.hide()
  6012.         if not driver['nonfreesoftware'] and not driver['patents']:
  6013.             self.rbtnNPDownloadLicenseYes.set_active(True)
  6014.             self.rbtnNPDownloadLicenseYes.hide()
  6015.             self.rbtnNPDownloadLicenseNo.hide()
  6016.         else:
  6017.             self.rbtnNPDownloadLicenseNo.set_active(True)
  6018.             self.rbtnNPDownloadLicenseYes.show()
  6019.             self.rbtnNPDownloadLicenseNo.show()
  6020.             self.frmNPDownloadableDriverLicenseTerms.show()
  6021.             terms = driver.get('licensetext', _('Not specified.'))
  6022.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  6023.         self.setNPButtons()
  6024.  
  6025.     
  6026.     def getNPPPD(self):
  6027.         
  6028.         try:
  6029.             if self.rbtnNPFoomatic.get_active():
  6030.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  6031.                 nr = model.get_path(iter)[0]
  6032.                 ppd = self.NPDrivers[nr]
  6033.             elif self.rbtnNPPPD.get_active():
  6034.                 ppd = cups.PPD(self.filechooserPPD.get_filename())
  6035.             else:
  6036.                 treeview = self.tvNPDownloadableDrivers
  6037.                 (model, iter) = treeview.get_selection().get_selected()
  6038.                 driver = model.get_value(iter, 1)
  6039.                 if driver.has_key('ppds'):
  6040.                     if len(driver['ppds']) > 0:
  6041.                         file_to_download = driver['ppds'][0]
  6042.                         debugprint('ppd file to download [' + file_to_download + ']')
  6043.                         file_to_download = file_to_download.strip()
  6044.                         if len(file_to_download) > 0:
  6045.                             ppdurlobj = urllib.urlopen(file_to_download)
  6046.                             ppdcontent = ppdurlobj.read()
  6047.                             ppdurlobj.close()
  6048.                             (tmpfd, ppdname) = tempfile.mkstemp()
  6049.                             debugprint(ppdname)
  6050.                             ppdfile = os.fdopen(tmpfd, 'w')
  6051.                             ppdfile.write(ppdcontent)
  6052.                             ppdfile.close()
  6053.                             ppd = cups.PPD(ppdname)
  6054.                             os.unlink(ppdname)
  6055.                         
  6056.                     
  6057.         except RuntimeError:
  6058.             e = None
  6059.             debugprint('RuntimeError: ' + str(e))
  6060.             if self.rbtnNPFoomatic.get_active():
  6061.                 err_title = _('Database error')
  6062.                 err_text = _("The '%s' driver cannot be used with printer '%s %s'.")
  6063.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  6064.                 nr = model.get_path(iter)[0]
  6065.                 driver = self.NPDrivers[nr]
  6066.                 if driver.startswith('gutenprint'):
  6067.                     err = _("You will need to install the '%s' package in order to use this driver.") % 'gutenprint-foomatic'
  6068.                 else:
  6069.                     err = err_text % (driver, self.NPMake, self.NPModel)
  6070.             elif self.rbtnNPPPD.get_active():
  6071.                 err_title = _('PPD error')
  6072.                 filename = self.filechooserPPD.get_filename()
  6073.                 err = _('Failed to read PPD file.  Possible reason follows:') + '\n'
  6074.                 
  6075.                 try:
  6076.                     p = subprocess.Popen([
  6077.                         '/usr/bin/cupstestppd',
  6078.                         '-rvv',
  6079.                         filename], stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  6080.                     (stdout, stderr) = p.communicate()
  6081.                     err += stdout
  6082.                 raise 
  6083.  
  6084.             else:
  6085.                 err_title = _('Downloadable drivers')
  6086.                 err = _('Failed to download PPD.')
  6087.             show_error_dialog(err_title, err, self.NewPrinterWindow)
  6088.             return None
  6089.         else:
  6090.             debugprint('ppd: ' + repr(ppd))
  6091.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6092.                 self.mainapp.cups._begin_operation(_('fetching PPD'))
  6093.                 
  6094.                 try:
  6095.                     if ppd != 'raw':
  6096.                         f = self.mainapp.cups.getServerPPD(ppd)
  6097.                         ppd = cups.PPD(f)
  6098.                         os.unlink(f)
  6099.                 except RuntimeError:
  6100.                     nonfatalException()
  6101.                     debugprint('libcups from CUPS 1.3 not available: never mind')
  6102.                 except cups.IPPError:
  6103.                     nonfatalException()
  6104.                     debugprint('CUPS 1.3 server not available: never mind')
  6105.  
  6106.                 self.mainapp.cups._end_operation()
  6107.             
  6108.  
  6109.         return ppd
  6110.  
  6111.     
  6112.     def fillNPInstallableOptions(self):
  6113.         debugprint('Examining installable options')
  6114.         self.installable_options = False
  6115.         self.options = { }
  6116.         container = self.vbNPInstallOptions
  6117.         for child in container.get_children():
  6118.             container.remove(child)
  6119.         
  6120.         if not self.ppd:
  6121.             l = gtk.Label(_('No Installable Options'))
  6122.             container.add(l)
  6123.             l.show()
  6124.             debugprint('No PPD so no installable options')
  6125.             return None
  6126.         for group in self.ppd.optionGroups:
  6127.             if group.name != 'InstallableOptions':
  6128.                 continue
  6129.             
  6130.             self.installable_options = True
  6131.             table = gtk.Table(1, 3, False)
  6132.             table.set_col_spacings(6)
  6133.             table.set_row_spacings(6)
  6134.             container.add(table)
  6135.             rows = 0
  6136.             for nr, option in enumerate(group.options):
  6137.                 if option.keyword == 'PageRegion':
  6138.                     continue
  6139.                 
  6140.                 rows += 1
  6141.                 table.resize(rows, 3)
  6142.                 o = OptionWidget(option, self.ppd, self)
  6143.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  6144.                 hbox = gtk.HBox()
  6145.                 if o.label:
  6146.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  6147.                     a.set_padding(0, 0, 0, 6)
  6148.                     a.add(o.label)
  6149.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6150.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6151.                 else:
  6152.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6153.                 hbox.pack_start(o.selector, False)
  6154.                 self.options[option.keyword] = o
  6155.             
  6156.         
  6157.         if not self.installable_options:
  6158.             l = gtk.Label(_('No Installable Options'))
  6159.             container.add(l)
  6160.             l.show()
  6161.         
  6162.         self.scrNPInstallableOptions.hide()
  6163.         self.scrNPInstallableOptions.show_all()
  6164.  
  6165.     
  6166.     def on_btnNPApply_clicked(self, widget):
  6167.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6168.             name = unicode(self.entNPName.get_text())
  6169.             location = unicode(self.entNPLocation.get_text())
  6170.             info = unicode(self.entNPDescription.get_text())
  6171.         else:
  6172.             name = self.mainapp.printer.name
  6173.         check = False
  6174.         checkppd = None
  6175.         ppd = self.ppd
  6176.         if self.dialog_mode == 'class':
  6177.             members = getCurrentClassMembers(self.tvNCMembers)
  6178.             
  6179.             try:
  6180.                 for member in members:
  6181.                     self.mainapp.cups.addPrinterToClass(member, name)
  6182.             except cups.IPPError:
  6183.                 (e, msg) = None
  6184.                 self.show_IPP_Error(e, msg)
  6185.                 return None
  6186.             
  6187.  
  6188.         None<EXCEPTION MATCH>cups.IPPError
  6189.         if self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  6190.             uri = None
  6191.             if self.device.uri:
  6192.                 uri = self.device.uri
  6193.             else:
  6194.                 uri = self.getDeviceURI()
  6195.             if not self.ppd:
  6196.                 self.nextNPTab(-1)
  6197.                 return None
  6198.             for option in self.options.itervalues():
  6199.                 option.writeback()
  6200.             
  6201.             self.busy(self.NewPrinterWindow)
  6202.             while gtk.events_pending():
  6203.                 gtk.main_iteration()
  6204.                 continue
  6205.                 self.ppd
  6206.             self.mainapp.cups._begin_operation(_('adding printer %s') % name)
  6207.             
  6208.             try:
  6209.                 if isinstance(ppd, str) or isinstance(ppd, unicode):
  6210.                     self.mainapp.cups.addPrinter(name, ppdname = ppd, device = uri, info = info, location = location)
  6211.                     check = True
  6212.                 elif ppd is None:
  6213.                     self.mainapp.cups.addPrinter(name, device = uri, info = info, location = location)
  6214.                 else:
  6215.                     cupshelpers.setPPDPageSize(ppd, self.language[0])
  6216.                     self.mainapp.cups.addPrinter(name, ppd = ppd, device = uri, info = info, location = location)
  6217.                     check = True
  6218.                     checkppd = ppd
  6219.             except cups.IPPError:
  6220.                 (e, msg) = None
  6221.                 self.ready(self.NewPrinterWindow)
  6222.                 self.show_IPP_Error(e, msg)
  6223.                 self.mainapp.cups._end_operation()
  6224.                 return None
  6225.                 self.ready(self.NewPrinterWindow)
  6226.                 self.mainapp.cups._end_operation()
  6227.                 fatalException(1)
  6228.  
  6229.             self.mainapp.cups._end_operation()
  6230.             self.ready(self.NewPrinterWindow)
  6231.         
  6232.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6233.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6234.             
  6235.             try:
  6236.                 cupshelpers.activateNewPrinter(self.mainapp.cups, name)
  6237.                 self.mainapp.cups.setPrinterLocation(name, location)
  6238.                 self.mainapp.cups.setPrinterInfo(name, info)
  6239.             except cups.IPPError:
  6240.                 (e, msg) = None
  6241.                 self.show_IPP_Error(e, msg)
  6242.                 self.mainapp.cups._end_operation()
  6243.                 return None
  6244.  
  6245.             self.mainapp.cups._end_operation()
  6246.         elif self.dialog_mode == 'device':
  6247.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6248.             
  6249.             try:
  6250.                 uri = self.getDeviceURI()
  6251.                 if not self.install_hplip_plugin(uri):
  6252.                     self.on_NPCancel(None)
  6253.                     return None
  6254.                 self.mainapp.cups.addPrinter(name, device = uri)
  6255.             except cups.IPPError:
  6256.                 (e, msg) = None
  6257.                 self.show_IPP_Error(e, msg)
  6258.                 self.mainapp.cups._end_operation()
  6259.                 return None
  6260.  
  6261.             self.mainapp.cups._end_operation()
  6262.         elif self.dialog_mode == 'ppd':
  6263.             if not ppd:
  6264.                 ppd = self.ppd = self.getNPPPD()
  6265.                 if not ppd:
  6266.                     self.nextNPTab(-1)
  6267.                     return None
  6268.             
  6269.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6270.             raw = False
  6271.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6272.                 if self.rbtnChangePPDasIs.get_active():
  6273.                     
  6274.                     try:
  6275.                         self.mainapp.cups.addPrinter(name, ppdname = 'raw')
  6276.                     except cups.IPPError:
  6277.                         (e, msg) = None
  6278.                         self.show_IPP_Error(e, msg)
  6279.                     except:
  6280.                         None<EXCEPTION MATCH>cups.IPPError
  6281.                     
  6282.  
  6283.                 None<EXCEPTION MATCH>cups.IPPError
  6284.                 
  6285.                 try:
  6286.                     self.mainapp.cups.addPrinter(name, ppdname = ppd)
  6287.                 except cups.IPPError:
  6288.                     (e, msg) = None
  6289.                     self.show_IPP_Error(e, msg)
  6290.                     self.mainapp.cups._end_operation()
  6291.                     return None
  6292.  
  6293.                 
  6294.                 try:
  6295.                     filename = self.mainapp.cups.getPPD(name)
  6296.                     ppd = cups.PPD(filename)
  6297.                     os.unlink(filename)
  6298.                 except cups.IPPError:
  6299.                     (e, msg) = None
  6300.                     if e == cups.IPP_NOT_FOUND:
  6301.                         raw = True
  6302.                     else:
  6303.                         self.show_IPP_Error(e, msg)
  6304.                         self.mainapp.cups._end_operation()
  6305.                         return None
  6306.                     e == cups.IPP_NOT_FOUND
  6307.                 
  6308.  
  6309.             None<EXCEPTION MATCH>cups.IPPError
  6310.             if not self.rbtnChangePPDasIs.get_active() and isinstance(self.mainapp.ppd, cups.PPD):
  6311.                 cupshelpers.copyPPDOptions(self.mainapp.ppd, ppd)
  6312.             else:
  6313.                 for option in self.options.itervalues():
  6314.                     option.writeback()
  6315.                 
  6316.                 cupshelpers.setPPDPageSize(ppd, self.language[0])
  6317.             
  6318.             try:
  6319.                 self.mainapp.cups.addPrinter(name, ppd = ppd)
  6320.             except cups.IPPError:
  6321.                 (e, msg) = None
  6322.                 self.show_IPP_Error(e, msg)
  6323.  
  6324.             self.mainapp.cups._end_operation()
  6325.             if not raw:
  6326.                 check = True
  6327.                 checkppd = ppd
  6328.             
  6329.         
  6330.         self.NewPrinterWindow.hide()
  6331.         self.mainapp.populateList()
  6332.         dests_iconview = self.mainapp.dests_iconview
  6333.         model = dests_iconview.get_model()
  6334.         iter = model.get_iter_first()
  6335.         while iter != None:
  6336.             queue = unicode(model.get_value(iter, 2))
  6337.             if queue == name:
  6338.                 path = model.get_path(iter)
  6339.                 dests_iconview.scroll_to_path(path, True, 0.5, 0.5)
  6340.                 dests_iconview.unselect_all()
  6341.                 dests_iconview.set_cursor(path)
  6342.                 dests_iconview.select_path(path)
  6343.                 break
  6344.             
  6345.             iter = model.iter_next(iter)
  6346.         self.mainapp.fillPrinterTab(name)
  6347.         self.mainapp.tvPrinterProperties.set_cursor((0,))
  6348.         if check:
  6349.             
  6350.             try:
  6351.                 self.checkDriverExists(name, ppd = checkppd)
  6352.             except:
  6353.                 nonfatalException()
  6354.  
  6355.             
  6356.             try:
  6357.                 option = self.mainapp.server_side_options['media']
  6358.                 if option.get_current_value() == None:
  6359.                     debugprint('Invalid media option: resetting')
  6360.                     option.reset()
  6361.                     self.mainapp.changed.add(option)
  6362.                     self.mainapp.save_printer(self.mainapp.printer)
  6363.             except KeyError:
  6364.                 pass
  6365.             except:
  6366.                 None<EXCEPTION MATCH>KeyError
  6367.                 nonfatalException()
  6368.             
  6369.  
  6370.         None<EXCEPTION MATCH>KeyError
  6371.         if (self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri') and self.mainapp.ppd != False:
  6372.             q = gtk.MessageDialog(self.mainapp.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _('Would you like to print a test page?'))
  6373.             response = q.run()
  6374.             q.destroy()
  6375.             if response == gtk.RESPONSE_YES:
  6376.                 self.mainapp.display_properties_dialog_for(name)
  6377.                 self.mainapp.PrinterPropertiesDialog.hide()
  6378.                 self.mainapp.btnPrintTestPage.clicked()
  6379.             
  6380.         
  6381.  
  6382.     
  6383.     def checkDriverExists(self, name, ppd = None):
  6384.         '''Check that the driver for an existing queue actually
  6385.         exists, and prompt to install the appropriate package
  6386.         if not.
  6387.  
  6388.         ppd: cups.PPD object, if already created'''
  6389.         server = cups.getServer()
  6390.         if not server == 'localhost' and server == '127.0.0.1' and server == '::1' or server[0] == '/':
  6391.             return None
  6392.         if not ppd:
  6393.             
  6394.             try:
  6395.                 filename = self.mainapp.cups.getPPD(name)
  6396.             except cups.IPPError:
  6397.                 server[0] == '/'
  6398.                 (e, msg) = server[0] == '/'
  6399.                 if e == cups.IPP_NOT_FOUND:
  6400.                     return None
  6401.                 self.show_IPP_Error(e, msg)
  6402.                 return None
  6403.             except:
  6404.                 e == cups.IPP_NOT_FOUND
  6405.  
  6406.             ppd = cups.PPD(filename)
  6407.             os.unlink(filename)
  6408.         
  6409.         (pkgs, exes) = cupshelpers.missingPackagesAndExecutables(ppd)
  6410.         if len(pkgs) > 0 or len(exes) > 0:
  6411.             can_install = False
  6412.             if len(pkgs) > 0:
  6413.                 
  6414.                 try:
  6415.                     pk = installpackage.PackageKit()
  6416.                     can_install = True
  6417.  
  6418.             
  6419.             if can_install and len(pkgs) > 0:
  6420.                 pkg = pkgs[0]
  6421.                 install_text = '<span weight="bold" size="larger">' + _('Install driver') + '</span>\n\n' + _("Printer '%s' requires the %s package but it is not currently installed.") % (name, pkg)
  6422.                 dialog = self.InstallDialog
  6423.                 self.lblInstall.set_markup(install_text)
  6424.                 dialog.set_transient_for(self.mainapp.PrintersWindow)
  6425.                 response = dialog.run()
  6426.                 dialog.hide()
  6427.                 if response == gtk.RESPONSE_OK:
  6428.                     
  6429.                     try:
  6430.                         xid = self.mainapp.PrintersWindow.window.xid
  6431.                         pk.InstallPackageName(xid, 0, pkg)
  6432.  
  6433.                 
  6434.             else:
  6435.                 show_error_dialog(_('Missing driver'), _("Printer '%s' requires the '%s' program but it is not currently installed.  Please install it before using this printer.") % (name, exes + pkgs[0]), self.mainapp.PrintersWindow)
  6436.         
  6437.  
  6438.  
  6439.  
  6440. def main(setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  6441.     cups.setUser(os.environ.get('CUPS_USER', cups.getUser()))
  6442.     gtk.gdk.threads_init()
  6443.     mainwindow = GUI(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6444.     if gtk.__dict__.has_key('main'):
  6445.         gtk.main()
  6446.     else:
  6447.         gtk.mainloop()
  6448.  
  6449. if __name__ == '__main__':
  6450.     import getopt
  6451.     
  6452.     try:
  6453.         (opts, args) = getopt.gnu_getopt(sys.argv[1:], '', [
  6454.             'setup-printer=',
  6455.             'configure-printer=',
  6456.             'choose-driver=',
  6457.             'devid=',
  6458.             'print-test-page=',
  6459.             'no-focus-on-map',
  6460.             'debug'])
  6461.     except getopt.GetoptError:
  6462.         show_help()
  6463.         sys.exit(1)
  6464.  
  6465.     setup_printer = None
  6466.     configure_printer = None
  6467.     change_ppd = False
  6468.     print_test_page = False
  6469.     focus_on_map = True
  6470.     devid = ''
  6471.     for opt, optarg in opts:
  6472.         if opt == '--configure-printer' and opt == '--choose-driver' or opt == '--print-test-page':
  6473.             configure_printer = optarg
  6474.             if opt == '--choose-driver':
  6475.                 change_ppd = True
  6476.             elif opt == '--print-test-page':
  6477.                 print_test_page = True
  6478.             
  6479.         elif opt == '--setup-printer':
  6480.             setup_printer = optarg
  6481.         elif opt == '--devid':
  6482.             devid = optarg
  6483.         elif opt == '--no-focus-on-map':
  6484.             focus_on_map = False
  6485.         elif opt == '--debug':
  6486.             set_debugging(True)
  6487.         
  6488.     
  6489.     main(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6490.  
  6491.